• 内核对象之信号量


    转载自:http://blog.csdn.net/morewindows/article/details/7481609

    步骤:

      1、CreateSemaphore,创建信号量

      2、WaitForSingleObject,获得信号量,使信息量减少

      3、ReleaseSemaphore,增加当前信号量的资源计数,表示有多少个线程正在运行,使信号量增加。

    对信号量的个人理解:

      1、用来计数

      2、用来同步

      3、将ReleaseSemaphore放在一个线程的开头

      4、信号量与事件内核对象有相同的同步功能

      5、由此可以更能加深对互斥量的认识,它能够解决“遗弃”问题,说明了互斥量的强大。 

    代码:

    #include <stdio.h>
    #include <process.h>
    #include <windows.h>
    long g_nNum;
    unsigned int __stdcall Fun(void *pPM);
    const int THREAD_NUM = 10;
    //信号量与关键段
    HANDLE            g_hThreadParameter;
    CRITICAL_SECTION  g_csThreadCode;
    int main()
    {
    	printf("     经典线程同步 信号量Semaphore
    ");
    	printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --
    
    ");
    
    	//初始化信号量和关键段
    	g_hThreadParameter = CreateSemaphore(NULL, 0, 1, NULL);//当前0个资源,最大允许1个同时访问
    	InitializeCriticalSection(&g_csThreadCode);
    
    	HANDLE  handle[THREAD_NUM];	
    	g_nNum = 0;
    	int i = 0;
    	while (i < THREAD_NUM) 
    	{
    		handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);
    		WaitForSingleObject(g_hThreadParameter, INFINITE);//等待信号量>0
    		++i;
    	}
    	WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);
    
    	//销毁信号量和关键段
    	DeleteCriticalSection(&g_csThreadCode);
    	CloseHandle(g_hThreadParameter);
    	for (i = 0; i < THREAD_NUM; i++)
    		CloseHandle(handle[i]);
    	return 0;
    }
    unsigned int __stdcall Fun(void *pPM)
    {
    	int nThreadNum = *(int *)pPM;
    
    	Sleep(50);//some work should to do
    
    	EnterCriticalSection(&g_csThreadCode);
    	++g_nNum;
    	Sleep(0);//some work should to do
    	printf("线程编号为%d  全局资源值为%d
    ", nThreadNum, g_nNum);
    	LeaveCriticalSection(&g_csThreadCode);
    
    	ReleaseSemaphore(g_hThreadParameter, 1, NULL);//信号量++
    	return 0;
    }
    

     结果:

    思考:

      当ReleaseSemaphore时,如果给第二个参数传入>1的数,则该程序停止了,看MSDN发现,如果第二个参数传入的值,会导致信号量的数量超过最大值,则不能成功执行。这就有问题了。信号资源只不过不能释放而已,还有其它资源也还是可以用的,为什么,这一个信号量没有释放,其它就不能得到信号,也许这就是信号源可以同步的原因,那么其实信号量同事件是差不多的,只不过在同步的时候,能够计数,计量的是已经在运行的线程数,也即是保证了最大的线程运行数,当超过这个数量的时候,就不再允许再创建,所以这个同步机制,多用于服务器,基于这种考虑,所以我们应该将ReleaseSemaphore放在线程的开头,以达到充分利用的目的。

  • 相关阅读:
    android 保存图片,及将图片更新到图库
    android 点击数字跳转到电话界面
    使用Picasso将加载的图片变成圆形
    如何获取listview里面的edittext或者RadioGroup的值,涉及到引发的混乱现象
    返回页面,并将此页面数据刷新一遍
    DrawerLayout建立侧滑时,显示侧滑页面,底层页面仍可以有点击响应,解决办法。
    实现双击退出程序
    sql语句查找某一列的值得最大值。
    vue 实战笔记一项目准备
    node的基础知识
  • 原文地址:https://www.cnblogs.com/wang-can/p/3334842.html
Copyright © 2020-2023  润新知