信号量(随意指定线程执行顺序)
来源:互联网 发布:怎么查网络是否丢包 编辑:程序博客网 时间:2024/05/20 11:33
HANDLE WINAPI CreateSemaphore( _In_opt_ LPSECURITY_ATTRIBUTES lpSemaphoreAttributes _In_ LONG lInitialCount, _In_ LONG lMaximumCount, _In_opt_ LPCTSTR lpName );
第一个参数:安全属性,如果为NULL则是默认安全属性
第二个参数:信号量的初始值,要>=0且<=第三个参数
第三个参数:信号量的最大值
第四个参数:信号量的名称
返回值:指向信号量的句柄,如果创建的信号量和已有的信号量重名,那么返回已经存在的信号量句柄
使用方法:
1、创建一个信号量:CreateSemaphore;
2、打开一个已经存在的信号量:OpenSemaphore;
3、获得信号量的一个占有权:WaitForSingleObject、WaitForMultipleObjects 等一类等待的函数……(可能造成阻塞);
4、释放信号量的占有权:ReleaseSemaphore;
5、关闭信号量:CloseHandle;
※ 命名标准:Semaphores 可以跨进程使用,所以其名称对整个系统而言是全局的,所以命名不要过于普通,类似:Semaphore、Object 等。
最好想一些独一无二的名字等!
固有特点(优点+缺点):
1、是一个系统核心对象,所以有安全描述指针,用完了要 CloseHandle 关闭句柄,这些是内核对象的共同特征;
2、因为是核心对象,所以执行速度稍慢(当然只是相比较而言);
3、因为是核心对象,而且可以命名,所以可以跨进程使用;
4、Semaphore 使用正确的情况下不会发生死锁;
5、在“等待”一个 信号量 的时候,可以指定“结束等待”的时间长度;
6、非排他性的占有,跟 Critical Sections 和 Mutex 不同,这两种而言是排他性占有,
即:同一时间内只能有单一线程获得目标并拥有操作的权利,而 Semaphores 则不是这样,
同一时间内可以有多个线程获得目标并操作!
信号量没有线程所有权属性,即一个线程获得某个信号量后,在他释放该信号量之前,他不能再次进入信号量保护的区域
信号量的使用规则:
1. 如果当前资源计数大于0,那么信号量处于触发状态;
2. 如果当前资源计数等于0,那么信号量处于未触发状态;那么系统会让调用线程进入等待状态。
CreateSemaphore(NULL,0,1,NULL); 当第二个参数为0时,调用线程就会进入等待状态
3. 系统绝对不会让当前资源计数变为负数;
4. 当前资源计数绝对不会大于最大资源计数。
编写一个程序,开启3个线程,这3个线程的ID分别为A、B、C,每个线程将自己的ID在屏幕上打印10遍,要求输出结果必须按ABC的顺序显示;如:ABCABC….依次递推。(修改顺序输出为ACBACB)
#include "stdafx.h"
#include <process.h>
#include <windows.h>
#include <iostream>
HANDLE hSemaphore[3] = {0};
int g_gloable = 100;
unsigned int WINAPI FunA(LPVOID lPvoid)
{
while (g_gloable>0)
{
WaitForSingleObject(hSemaphore[0], INFINITE);
std::cout << "A" << std::endl;
g_gloable -= 1;
ReleaseSemaphore(hSemaphore[2],1,NULL);//递增信号量C的资源数
}
return 0;
}
unsigned int WINAPI FunB(LPVOID lPvoid)
{
while (g_gloable>0)
{
WaitForSingleObject(hSemaphore[1], INFINITE);
std::cout << "B" << std::endl;
g_gloable -= 1;
ReleaseSemaphore(hSemaphore[0], 1, NULL);//递增信号量A的资源数
}
return 0;
}
unsigned int WINAPI FunC(LPVOID lPvoid)
{
while (g_gloable>0)
{
WaitForSingleObject(hSemaphore[2], INFINITE);
std::cout << "C" << std::endl;
g_gloable -= 1;
ReleaseSemaphore(hSemaphore[1], 1, NULL);//递增信号量B的资源数
}
return 0;
}
int _tmain(int argc, _TCHAR* argv[])
{
hSemaphore[0] = CreateSemaphore(NULL,1,1,NULL);
hSemaphore[1] = CreateSemaphore(NULL, 0, 1, NULL);
hSemaphore[2] = CreateSemaphore(NULL, 0, 1, NULL);
HANDLE handle[3];
handle[0] = (HANDLE)_beginthreadex(NULL,0,FunA,0,0,NULL);
handle[1] = (HANDLE)_beginthreadex(NULL, 0, FunB, 0, 0, NULL);
handle[2] = (HANDLE)_beginthreadex(NULL, 0, FunC, 0, 0, NULL);
WaitForMultipleObjects(3,handle,true,INFINITE);
CloseHandle(hSemaphore[0]);
CloseHandle(hSemaphore[1]);
CloseHandle(hSemaphore[2]);
CloseHandle(handle[0]);
CloseHandle(handle[1]);
CloseHandle(handle[2]);
return 0;
}
- 信号量(随意指定线程执行顺序)
- Java 指定线程执行顺序(三种方式)
- Java 指定线程执行顺序(三种方式)
- Java-按指定顺序执行线程
- iOS 通过添加线程依赖和信号量结合实现一个复杂界面请求多个接口时按指定顺序执行
- 使用信号量控制线程执行顺序,进而控制不同视频流的解码顺序
- 线程顺序执行(phtread)
- 控制线程顺序执行
- 线程执行顺序例子
- 三个线程顺序执行
- thread 线程执行顺序
- Junit指定测试执行顺序
- JAVA多线程顺序执行(使用join,lock,condition,信号量)原理和java源代码
- Java 线程的执行顺序
- JAVA线程分组顺序执行
- CountDownLatch控制线程执行顺序
- java 线程按顺序执行
- Android中让多个线程顺序执行
- 链表
- jQueryMobile事件
- 论文阅读 Learning Affinity via Spatial Propagation Networks
- ShadowsocksR一键安装脚本
- python测试Android项目,报错执行登录测试用例 <_io.TextIOWrapper name='<stderr>' mode='w' encoding='cp936'> 麻烦帮忙看下,谢谢
- 信号量(随意指定线程执行顺序)
- VGG Pool5 Feature Map特征提取
- 史上最简单的SpringCloud教程 | 第三篇: 服务消费者(Feign)
- MySQL必知必会
- php7.1.10启动报错127.0.0.1:9000端口占用解决之道
- Android 自定义alertDialog
- 多层文字滚动
- LeetCode(6) ZigZag Conversion解题报告
- 12.13课堂笔记、课后作业、学习心得