多线程第五篇 经典线程同步之信号量Semaphore

转载 2015年07月09日 11:44:43

1、首先来看看如何使用信号量

    信号量Semaphore常用有三个函数,使用很方便。下面是这几个函数的原型和使用说明。

第一个 CreateSemaphore

函数功能:创建信号量

函数原型:

HANDLE CreateSemaphore(

  LPSECURITY_ATTRIBUTES lpSemaphoreAttributes,

  LONG lInitialCount,

  LONG lMaximumCount,

  LPCTSTR lpName

);

函数说明:

第一个参数表示安全控制,一般直接传入NULL

第二个参数表示初始资源数量。

第三个参数表示最大并发数量。

第四个参数表示信号量的名称,传入NULL表示匿名信号量。

第二个 OpenSemaphore

函数功能:打开信号量

函数原型:

HANDLE OpenSemaphore(

  DWORD dwDesiredAccess,

  BOOL bInheritHandle,

  LPCTSTR lpName

);

函数说明:

第一个参数表示访问权限,对一般传入SEMAPHORE_ALL_ACCESS。详细解释可以查看MSDN文档。

第二个参数表示信号量句柄继承性,一般传入TRUE即可。

第三个参数表示名称,不同进程中的各线程可以通过名称来确保它们访问同一个信号量。

第三个 ReleaseSemaphore

函数功能:递增信号量的当前资源计数

函数原型:

BOOL ReleaseSemaphore(

  HANDLE hSemaphore,

  LONG lReleaseCount

  LPLONG lpPreviousCount

);

函数说明:

第一个参数是信号量的句柄。

第二个参数表示增加个数,必须大于0且不超过最大资源数量。

第三个参数可以用来传出先前的资源计数,设为NULL表示不需要传出。

       注意:当前资源数量大于0,表示信号量处于触发,等于0表示资源已经耗尽故信号量处于末触发。在对信号量调用等待函数时,等待函数会检查信号量的当前资源计数,如果大于0(即信号量处于触发状态),减1后返回让调用线程继续执行。一个线程可以多次调用等待函数来减小信号量。

最后一个 信号量的清理与销毁

由于信号量是内核对象,因此使用CloseHandle()就可以完成清理与销毁了。

2、在经典多线程问题中设置一个信号量和一个关键段。用信号量处理主线程与子线程的同步,用关键段来处理各子线程间的互斥。详见代码:

[html] view plaincopy
  1. #include <stdio.h>  
  2. #include <process.h>  
  3. #include <windows.h>  
  4. long g_nNum;  
  5. unsigned int __stdcall Fun(void *pPM);  
  6. const int THREAD_NUM = 10;  
  7. //信号量与关键段  
  8. HANDLE            g_hThreadParameter;  
  9. CRITICAL_SECTION  g_csThreadCode;  
  10. int main()  
  11. {  
  12.     printf("     经典线程同步 信号量Semaphore\n");  
  13.     printf(" -- by MoreWindows( http://blog.csdn.net/MoreWindows ) --\n\n");  
  14.   
  15.     //初始化信号量和关键段  
  16.     g_hThreadParameter = CreateSemaphore(NULL, 0, 1, NULL);//当前0个资源,最大允许1个同时访问  
  17.     InitializeCriticalSection(&g_csThreadCode);  
  18.   
  19.     HANDLE  handle[THREAD_NUM];   
  20.     g_nNum = 0;  
  21.     int i = 0;  
  22.     while (i < THREAD_NUM)   
  23.     {  
  24.         handle[i] = (HANDLE)_beginthreadex(NULL, 0, Fun, &i, 0, NULL);  
  25.         WaitForSingleObject(g_hThreadParameter, INFINITE);//等待信号量>0  
  26.         ++i;  
  27.     }  
  28.     WaitForMultipleObjects(THREAD_NUM, handle, TRUE, INFINITE);  
  29.       
  30.     //销毁信号量和关键段  
  31.     DeleteCriticalSection(&g_csThreadCode);  
  32.     CloseHandle(g_hThreadParameter);  
  33.     for (i = 0; i < THREAD_NUM; i++)  
  34.         CloseHandle(handle[i]);  
  35.     return 0;  
  36. }  
  37. unsigned int __stdcall Fun(void *pPM)  
  38. {  
  39.     int nThreadNum = *(int *)pPM;  
  40.     ReleaseSemaphore(g_hThreadParameter, 1, NULL);//信号量++  
  41.   
  42.     Sleep(50);//some work should to do  
  43.   
  44.     EnterCriticalSection(&g_csThreadCode);  
  45.     ++g_nNum;  
  46.     Sleep(0);//some work should to do  
  47.     printf("线程编号为%d  全局资源值为%d\n", nThreadNum, g_nNum);  
  48.     LeaveCriticalSection(&g_csThreadCode);  
  49.     return 0;  
  50. }  

运行结果:

可以看出来,信号量也可以解决线程之间的同步问题。

        由于信号量可以计算资源当前剩余量并根据当前剩余量与零比较来决定信号量是处于触发状态或是未触发状态,因此信号量的应用范围相当广泛。本系列的《多线程八 生产者消费者经典问题》将再次使用它来解决线程同步问题,欢迎大家参阅。

        至此,经典线程同步问题全部结束了,下一篇《多线程七 经典线程同步与互斥总结》将会对其作个总结以梳理各知识点。

文章转载于:http://blog.csdn.net/morewindows/article/details/7481609

相关文章推荐

多线程之八 经典线程同步 信号量Semaphore

前面介绍了关键段CS、事件Event、互斥量Mutex在经典线程同步问题中的使用。本篇介绍用信号量Semaphore来解决这个问题。 首先也来看看如何使用信号量,信号量Semaphore常用有三个函...

多线程六 经典线程同步之信号量Semaphore

1、首先来看看如何使用信号量     信号量Semaphore常用有三个函数,使用很方便。下面是这几个函数的原型和使用说明。 第一个 CreateSemaphore 函数功能:创建信号量 函...

秒杀多线程第八篇 经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇: 《秒杀多线程第四篇一个经典的多线程同步问题》 《秒杀多线程第五篇经典线程同步关键段CS》 《秒杀多线程第六篇经典线程同步事件Event》 《秒...

秒杀多线程第八篇---经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇: 《秒杀多线程第四篇一个经典的多线程同步问题》 《秒杀多线程第五篇经典线程同步关键段CS》 《秒杀多线程第六篇经典线程同步事件Event》 《秒杀多线程第七篇经...
  • will130
  • will130
  • 2015年11月27日 14:32
  • 275

秒杀多线程第八篇 经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇: 《秒杀多线程第四篇一个经典的多线程同步问题》 《秒杀多线程第五篇经典线程同步关键段CS》 《秒杀多线程第六篇经典线程同步事件Event》 《秒杀多线程第七篇经...

秒杀多线程第八篇 经典线程同步 信号量Semaphore

阅读本篇之前推荐阅读以下姊妹篇:《秒杀多线程第四篇一个经典的多线程同步问题》《秒杀多线程第五篇经典线程同步关键段CS》《秒杀多线程第六篇经典线程同步事件Event》《秒杀多线程第七篇经典线程同步互斥量...

秒杀多线程第五篇 经典线程同步 关键段CS

上一篇《秒杀多线程第四篇 一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题。本文首先介绍下如何使用关键段,然后再深层次的分...

秒杀多线程第五篇 经典线程同步 关键段(临界区,CriticalSection)

上一篇《秒杀多线程第四篇 一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题。 本文首先介绍下如何使用关键段,然后再深...

秒杀多线程第五篇---经典线程同步 关键段(临界区)CS

上一篇《秒杀多线程第四篇 一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题。本文首先介绍下如何使用关键段,然后再深层次的分...
  • will130
  • will130
  • 2015年11月12日 21:24
  • 432

秒杀多线程第五篇 经典线程同步 关键段CS

上一篇《秒杀多线程第四篇 一个经典的多线程同步问题》提出了一个经典的多线程同步互斥问题,本篇将用关键段CRITICAL_SECTION来尝试解决这个问题。 本文首先介绍下如何使用关键段,然后再深...
  • JXH_123
  • JXH_123
  • 2014年04月11日 15:20
  • 417
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多线程第五篇 经典线程同步之信号量Semaphore
举报原因:
原因补充:

(最多只允许输入30个字)