C++ 信号量 多线程同步互斥
2016-05-17 11:11
375 查看
信号量对象对线程的同步方式与前面几种方法不同,信号允许多个线程同时使用共享资源,这与操作系统中的PV操作相同。它指出了同时访问共享资源的线程 最大数目。它允许多个线程在同一时刻访问同一资源,但是需要限制在同一时刻访问此资源的最大线程数目。在用CreateSemaphore()创建信号量 时即要同时指出允许的最大资源计数和当前可用资源计数。一般是将当前可用资源计数设置为最大资源计数,每增加一个线程对共享资源的访问,当前可用资源计数 就会减1,只要当前可用资源计数是大于0的,就可以发出信号量信号。但是当前可用计数减小到0时则说明当前占用资源的线程数已经达到了所允许的最大数目, 不能在允许其他线程的进入,此时的信号量信号将无法发出。线程在处理完共享资源后,应在离开的同时通过ReleaseSemaphore()函数将当前可 用资源计数加1。在任何时候当前可用资源计数决不可能大于最大资源计数。
PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。
P操作 申请资源:
(1)S减1;
(2)若S减1后仍大于等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。
V操作 释放资源:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。
信号量包含的几个操作原语:
CreateSemaphore() 创建一个信号量
OpenSemaphore() 打开一个信号量
ReleaseSemaphore() 释放信号量
WaitForSingleObject() 等待信号量
PV操作及信号量的概念都是由荷兰科学家E.W.Dijkstra提出的。信号量S是一个整数,S大于等于零时代表可供并发进程使用的资源实体数,但S小于零时则表示正在等待使用共享资源的进程数。
P操作 申请资源:
(1)S减1;
(2)若S减1后仍大于等于零,则进程继续执行;
(3)若S减1后小于零,则该进程被阻塞后进入与该信号相对应的队列中,然后转入进程调度。
V操作 释放资源:
(1)S加1;
(2)若相加结果大于零,则进程继续执行;
(3)若相加结果小于等于零,则从该信号的等待队列中唤醒一个等待进程,然后再返回原进程继续执行或转入进程调度。
信号量包含的几个操作原语:
CreateSemaphore() 创建一个信号量
OpenSemaphore() 打开一个信号量
ReleaseSemaphore() 释放信号量
WaitForSingleObject() 等待信号量
#include <Windows.h> #include <stdio.h> HANDLE hSemaphore = NULL; const char* strSemaphoreName = "MySemaphore"; const int threads_num = 50; HANDLE Threads[threads_num]; bool bExitThreads = FALSE; void WINAPI ThreadFun(void* param) { printf("线程 %u 开始运行\n", GetCurrentThreadId()); WaitForSingleObject(hSemaphore,INFINITE); printf("线程 %u 获得信号量,继续运行\n", GetCurrentThreadId()); while(!bExitThreads) { Sleep(10); } long dwSem = 0; if (!ReleaseSemaphore(hSemaphore, 1, &dwSem)) { if (0 == GetLastError()) { printf("当前可用资源数:20\n"); return; } } printf("当前可用资源数:%u\n", dwSem); } void creatThreads() { DWORD dwThreadID = 0; for (int i =0; i < threads_num; ++i) { Threads[i] = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)ThreadFun, NULL, 0, &dwThreadID); if (!Threads[i]) { printf("创建线程失败!\n"); } printf("线程 %u 创建成功\n", dwThreadID); } } void main() { hSemaphore = CreateSemaphoreA(NULL, 0, 20, strSemaphoreName); if(NULL == (hSemaphore = OpenSemaphoreA(SEMAPHORE_MODIFY_STATE , FALSE, strSemaphoreName))) { printf("打开信号量对象失败 , 错误ID:%u\n", GetLastError()); return; } creatThreads(); bExitThreads = true; WaitForMultipleObjects(threads_num, Threads, TRUE, INFINITE); }
相关文章推荐
- 00_ubuntu下vim的c++补全
- Geekband C++面向对象高级编程(上) 第二周笔记 暗影行者
- 巧妙程序写法
- c/c++ 结束进程
- C++ local static对象和non-local static对象在初始化时机上的差异
- C语言练习题:自由落体的小球简单实例
- 新增的C语言完整源代码
- C语言练习题:求1到10的阶乘之和简单实例
- OpenCV中C++函数imread读取图片的缩放问题
- C++程序设计必知:常引用、常对象和对象的常成员
- C / C++ 输入输出缓存处理
- C语言指针变量可以当做数组运用
- 2016年,C语言该怎样写
- gsoap笔记 C++
- 330. Patching Array (C++实现)
- 深入理解C++中public、protected及private用法
- OC语言笔记(十二):OC字符串、数组、字典常用方法大全
- OC语言笔记(十一):OC沙盒查找步骤
- C#调用C++DLL的小总结5---和C++的DLL的联合调试
- 第8周 C语言及程序设计提高例程-30 字符和字符串处理函数