多线程第五篇 经典线程同步之信号量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)

多线程同步之Semaphore (主要解决生产者消费者问题) 一 信标Semaphore 信标内核对象用于对资源进行计数。它们与所有内核对象一样,包含一个使用数量,但是它们也包含另外两个带符号...
  • zhang_sinner
  • zhang_sinner
  • 2015年02月11日 21:43
  • 933

C++多线程同步之Semaphore(信号量)

一、线程间同步的几种方式从上篇博文中可以发现,当多个线程对同一资源进行使用时,会产生“争夺”的情况,为了避免这种情况的产生,也就出现了线程间的同步这个技术。线程间的同步有多种方式,在接下来的博文中我会...
  • oLanSeFengYe1
  • oLanSeFengYe1
  • 2016年10月24日 16:06
  • 1457

C语言多线程同步 -- 信号量semaphore.h

多线程读文件使用fopen,出现BUG,然后寻找同步方法,找到这个“信号量“。 首先需要用sem_init(); 初始化sem_t型变量,并设置初始信号量。比如设置为1. 每次调用sem_wait(s...
  • OOC_ZC
  • OOC_ZC
  • 2016年02月24日 13:43
  • 5568

多线程编程(三)——线程同步——信号量

线程同步主要为了协调线程间工作,尤其是数据的使用, 第一个例子——生产者消费者: 设置: #库存最多1,有库存消费者才消费,没则等待;没库存生产者才生产,没则等待。 #并没有用semA本身做...
  • huqinweI987
  • huqinweI987
  • 2016年03月17日 16:34
  • 1134

分布式同步、信号量

分布试系统中经常出现多个进程请求访问同一临界资源的问题。       目前, 对临界区进行控制访问的方法主要有三种: 集中式算法、令牌环算法和分布式算法。集中式算法类似于单处理机上的信号量方法,...
  • cxzhq2002
  • cxzhq2002
  • 2014年04月08日 23:43
  • 997

秒杀多线程-经典线程同步之信号量Semaphore

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

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

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

在VC6.0中多线程编程示例(带同步信号量)

直接上代码:#include //必要的头文件,使用Windows API函数 #include int index = 0; int tickets = 100;//票数 HANDLE hMut...
  • eifjgoergfgrgr
  • eifjgoergfgrgr
  • 2014年07月07日 14:28
  • 1898

《java并发编程实战》:线程同步辅助类之信号量(semaphore)

1.信号量的概念: 信号量是一种计数器,用来保护一个或者多个共享资源的访问,它是并发编程的一种基础工具,大多数编程语言都提供了这个机制。 2、信号量控制线程访问流程: 如果线程要访问一个共享资源,...
  • u010758482
  • u010758482
  • 2016年10月16日 22:31
  • 295

线程同步互斥之信号量对象(Semaphore)

信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程和进程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程最大数目。它允许多个线程在同一时刻访问同一资源,但是需...
  • u013421892
  • u013421892
  • 2015年08月21日 17:45
  • 635
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:多线程第五篇 经典线程同步之信号量Semaphore
举报原因:
原因补充:

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