博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
信号量
阅读量:4583 次
发布时间:2019-06-09

本文共 3152 字,大约阅读时间需要 10 分钟。

  • 互斥量:某段时间只能让一个线程运行,其他休眠。
  • 信号量:多个线程运行,其他线程休眠
  • 临界区:只能让一个线程运行,其他休眠。
  • 原子操作:操作速度最快,因为他不需要等待和切换线程。
  • 事件也可以实现线程互斥。

1.信号量

 主要解决线程通信,实现同一时刻多个线程同时访问一个资源,当同一时刻只有一个线程在访问时它就和互斥量是一样的,所以有时说信号量是Mutex的退化版。它也是系统内核对象. 系统提供相关的API有:

CreateSemaphore

OpenSemaphore

ReleaseSemaphore

WaitForSingleObject/WaitForMultipleObjects

CloseHandle

2.理解

  • Semaphore分为单值和多值两种,前者只能被一个线程获得,后者可以被若干个线程获得。
    以 一个停车场是运作为例。为了简单起见,假设停车场只有三个车位,一开始 三个车位都是空的。这时如果同时来了五辆车,看门人允许其中三辆不受阻碍的进入,然后放下车拦,剩下的车则必须在入口等待,此后来的车也都不得不在入口处 等待。这时,有一辆车离开停车场,看门人得知后,打开车拦,放入一辆,如果又离开两辆,则又可以放入两辆,如此往复。
    在这个 中,车位是公共资源,每辆车好比一个线程,看门人起的就是 的作用。
  • Mutex是一把钥匙,一个人拿了就可进入一个房间,出来的时候把钥匙交给队列的第一个。一般的用法是用于串行化对critical section代码的访问,保证这段代码不会被并行的运行。
    Semaphore是一件可以容纳N人的房间,如果人不满就可以进去,如果人满了,就要等待有人出来。对于N=1的情况,称为binary semaphore。一般的用法是,用于限制对于某一资源的同时访问。

3.函数的参数

CloaseHandle(thread);thread线程执行完毕,然后退出。
当信号量设置是1,也可以实现互斥。
信号量遇到0就死等,遇到其他数,减1.

2.例子

例一:

//关卡的作用#include 
#include
#include
#define id "haihua"#define MAX 5//0无限等待DWORD WINAPI myworker(void *p){ int *pint = p; printf("\nmyworker%d is running", *pint); HANDLE myhsem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, id);//打开一个信号 if (myhsem) //myheasm!=null { printf("\nmyworker%d is waitting", *pint); //初始化信号为0,为0就会死锁,0,信号量不减去 //WaitForSingleObject不为 0的情况下,信号量-1 if (WaitForSingleObject(myhsem,INFINITE)==WAIT_OBJECT_0)//等到了信号 { printf("\nmyworker%d is gettting", *pint); Sleep(3000); printf("\nmyworker%d is leaving,", *pint); ///ReleaseSemaphore(myhsem, 1, NULL);//释放资源 ,+1 CloseHandle(myhsem);//执行完成退出 } } return 1;}int main(){ //创建信号对象, HANDLE hSEM = CreateSemaphore(NULL, 0, MAX, id);//开辟一个信号,最大计数是5.0 int a[10] = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 }; HANDLE hd[10] = { 0 }; for (int i = 0; i < 10;i++) { hd[i] = CreateThread(NULL, 0, myworker, a + i, 0, NULL);//创建是个线程 } Sleep(5000); printf("激活线程"); ReleaseSemaphore(hSEM, MAX, NULL); //最多一次放过5 WaitForMultipleObjects(10, hd, TRUE, INFINITE); CloseHandle(hSEM); system("pause");}

 

例二:

#include 
#include
#include
int num = 0;DWORD WINAPI add(void*p){ HANDLE myhsem = OpenSemaphore(SEMAPHORE_ALL_ACCESS, FALSE, "xiaobin");//打开一个信号 if (myhsem) //myheasm!=null { if (WaitForSingleObject(myhsem, INFINITE) == WAIT_OBJECT_0)//等到了信号 { for (int i = 0; i < 100000; i++) { num++; } ReleaseSemaphore(myhsem, 1, NULL); CloseHandle(myhsem);//执行完成退出 } } else { printf("信号量获取失败\n"); }}int main(){ //创建信号对象, HANDLE hSEM = CreateSemaphore(NULL, 0, 1, "xiaobin");//开辟一个信号,最大计数是5.0 HANDLE hd[64] = { 0 }; for (int i = 0; i < 64; i++) { hd[i] = CreateThread(NULL, 0, add,NULL, 0, NULL);//创建是个线程 } Sleep(2000); printf("激活线程"); ReleaseSemaphore(hSEM, 1, NULL); WaitForMultipleObjects(64, hd, TRUE, INFINITE); printf("%d", num); CloseHandle(hSEM); system("pause");}

 

转载于:https://www.cnblogs.com/sjxbg/p/5789781.html

你可能感兴趣的文章
奇偶数分离
查看>>
1020 PAT
查看>>
hdu6080(最小环)
查看>>
背景透明,文字不透明解决办法
查看>>
微信小程序 报错: Expecting 'EOF','}',',',']', got INVALID
查看>>
mysql 数据库【目录】
查看>>
开发工具IDEA环境安装配置
查看>>
python3正则表达式详细用法示例
查看>>
算法笔记_086:蓝桥杯练习 9-2 文本加密(Java)
查看>>
Win8下使用Ctrl加空格来切换输入法
查看>>
ajax分页
查看>>
Java 常量池理解与总结(转摘)
查看>>
多线程编程学习笔记——线程池(三)
查看>>
从开始学编程过了半年了……
查看>>
【05月22日】预分红股息率最高排名
查看>>
Android学习总结(二)——Service基本概念和生命周期
查看>>
chr()//ord() //进制转换函数//eval()//文件函数//split()
查看>>
第一章 Java程序设计概述
查看>>
定时调动 (项目保留备份代码码)
查看>>
Leetcode-Divide Two Integers
查看>>