转—秒杀多线程第八首 经典线程同步 信号量Semaphore

看本篇在此以前推荐阅读以下姊妹篇:

秒杀多线程第四篇一个经文的多线程同步问题

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

秒杀多线程第六首经典线程同步事件伊芙(Eve)nt

秒杀多线程第七篇经典线程同步互斥量Mutex

 

面前介绍了关键段CS事件Event互斥量Mutex于经线程同步问题屡遭之运。本篇介绍用信号量Semaphore来解决这多少个题目。

先是为来探哪利用信号量,信号量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()就足以做到清理和销毁了。

 

每当藏多线程问题遭逢安装一个信号量和一个要段。用信号量处理主线程和子线程的并,用要段来拍卖各子线程间的排挤。详见代码:

[cpp] view
plain
copy

  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. }  

运作结果要下图:

图片 1

好关押出来,信号量也可缓解线程之间的齐问题。

 

出于信号量可以测算资源时剩余量并冲近年来剩余量与零散较来决定信号量是居于触发状态恐怕未触发状态,因而信号量的应用范围优良普遍。本体系的《秒杀多线程第十首
生产者消费者问题》将再也行使她来化解线程同步问题,欢迎我们参考。

 

由来,经典线程同步问题总体了事了,下一致首《秒杀多线程第九首经文多线程同步问题总》将会见针对该犯个小结为梳理各类知识点。

 

转载请标明出处,原文地址:http://blog.csdn.net/morewindows/article/details/7481609

而以为本文对你来帮带,请点击‘顶’辅助一下,您的支撑是自家作最深的引力,谢谢。

相关文章