转载出处:秒杀多线程第八篇 经典线程同步 信号量Semaphore
学习笔记:
看了一下作者写的列子,下面写一下自己的理解。代码部分如下:
步,用关键段来处理各子线程间的互斥。详见代码:
- #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\n");
- printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");
-
-
- g_hThreadParameter = CreateSemaphore(NULL, 0, 1, NULL);
- //创建信号量这个函数在传入的第二和第三个参数是很重要的,必须明确要传入的值。
- //第二个参数表示当前资源的个数,如果传入0,那么下面的WaitForSingleObject就会阻塞等待资源个数大于0,如 果初始化大于0的话WaitForSingleObject将不会阻塞等待,那么信号量的作用在此处就失去了意义。
- //第三个参数表示最大的并发数量
- 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);
- ++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;
- ReleaseSemaphore(g_hThreadParameter, 1, NULL);
-
- Sleep(50);
-
- EnterCriticalSection(&g_csThreadCode);
- ++g_nNum;
- Sleep(0);
- printf("线程编号为%d 全局资源值为%d\n", nThreadNum, g_nNum);
- LeaveCriticalSection(&g_csThreadCode);
- return 0;
- }
有上可知,当程序_beginthreadex第一个线程的后,由于初始化资源个数为0,所以WaitForSingleObject将等待资源个数大于0,即等待信号量触发(ReleaseSemaphore)对资源计数++,然后才做第二次_beginthreadex,这样就达到了同步的效果。