博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
12、第七 - 网络编程基础 - 线程中的信号量(Semaphore)
阅读量:5321 次
发布时间:2019-06-14

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

  

  互斥锁同时只允许一个线程更改数据,而Semaphore是同时允许一定数量的线程更改数据。简单介绍如下:

  信号量用在多线程多任务同步的,一个线程完成了某一个动作就通过信号量告诉别的线程,别的线程再进行某些动作。而互斥锁是用在多线程多任务互斥的,一个线程占用了某一个资源,那么别的线程就无法访问,直到这个线程unlock,其他的线程才开始可以利用这 个资源。比如对全局变量的访问,有时要加锁,操作完了,在解锁。有的时候锁和信号量会同时使用的。

  也就是说,信号量不一定是锁定某一个资源,而是流程上的概念,比如:有A,B两个线程,B线程要等A线程完成某一任务以后再进行自己下面的步骤,这个任务 并不一定是锁定某一资源,还可以是进行一些计算或者数据处理之类。而线程互斥锁则是“锁住某一资源”的概念,在锁定期间内,其他线程无法对被保护的数据进 行操作。在有些情况下两者可以互换。

信号量(Semaphore),有时被称为信号灯,是在多线程环境下使用的一种设施, 它负责协调各个线程, 以保证它们能够正确、合理的使用公共资源。

  • 创建 Create
  • 等待 Wait::线程等待信号量,如果值大于0,则获得,值减一;如果只等于0,则一直线程进入睡眠状态,知道信号量值大于0或者超时。
  • 释放 Post:执行释放信号量,则值加一;如果此时有正在等待的线程,则唤醒该线程。
  • 试图等待 TryWait:如果调用TryWait,线程并不真正的去获得信号量,还是检查信号量是否能够被获得,如果信号量值大于0,则TryWait返回成功;否则返回失败。
  • 销毁 Destroy

   Mutex本质上说就是一把锁,提供对资源的独占访问,所以Mutex主要的作用是用于互斥。Mutex对象的值,只有0和1两个值。这两个值也分别代表了Mutex的两种状态。值为0, 表示锁定状态,当前对象被锁定,用户进程/线程如果试图Lock临界资源,则进入排队等待;值为1,表示空闲状态,当前对象为空闲,用户进程/线程可以Lock临界资源,之后Mutex值减1变为0。

Mutex可以被抽象为四个操作:

  • 创建 Create
  • 加锁 Lock
  • 解锁 Unlock
  • 销毁 Destroy

互斥锁和信号量的区别:

  • 互斥量用于线程的互斥,信号量用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。 
  1. 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
  2. 信号:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
  • 互斥量值只能为0/1,信号量值可以为非负整数。
  1. 也就是说,一个互斥量只能用于一个资源的互斥访问,它不能实现多个资源的多线程互斥问题。信号量可以实现多个同类资源的多线程互斥和同步。当信号量为单值信号量是,也可以完成一个资源的互斥访问。
  • 互斥量的加锁和解锁必须由同一线程分别对应使用,信号量可以由一个线程释放,另一个线程得到

举例:有三个公共电话亭,同时可以三个人打电话。这时候有人过来要打电话,就出现了等待。要等会里面的人出来后(里面的人出来这一动作,就相当于信号,告诉外面的人,到你打电话了),外面的人才能进去,进行下一步操作。

import threading,timedef run(n):    semaphore.acquire()    time.sleep(1)    print ("run the  thread:%s\n " % n)    semaphore.release()if __name__ == "__main__":    semaphore = threading.BoundedSemaphore(4) #最多允许4个线程同时运行    for i in range(10):        t = threading.Thread(target=run,args=(i,))        t.start()while threading.active_count() != 1:    passelse:    print("--all thread done--")输出:run the  thread:0run the  thread:1run the  thread:2run the  thread:3 run the  thread:4run the  thread:7run the  thread:5run the  thread:6 run the  thread:9run the  thread:8 --all thread done--Process finished with exit code 0 备注:每次执行4个线程,等前面执行完成后,在进行下一个。最后剩下两个,会一起执行。整个执行过程中是无序的。

 

转载于:https://www.cnblogs.com/chen170615/p/8746546.html

你可能感兴趣的文章
JAVA对象转化JSON出现死循环问题
查看>>
开始写博客啦
查看>>
ThreadLocal
查看>>
ionic3 打开相机与相册,并实现图片上传
查看>>
在多于16核心的服务器上安装Media Service时应注意 Media Server无法启动的问题。
查看>>
LightOJ 1370- Bi-shoe and Phi-shoe
查看>>
AFNetworking实现 断点续传
查看>>
[leetcode]不同路径三连击~
查看>>
kb-09-线段树--区间合并比较繁
查看>>
直接拿来用!最火的Android开源项目(完结篇)
查看>>
[PAT] 1022 Digital Library (30 分) Java
查看>>
使用rapid-framework3.5结合sqlserver2005快速开发
查看>>
python学习第二篇
查看>>
[转] Download Images from Multiple Maps
查看>>
一次linux服务器Read-only file system的修复过程
查看>>
城市计算:给我们生活的城市装上了智能引擎
查看>>
最大子段和_算法与数据结构_Python
查看>>
python复习之路-Day01
查看>>
UVa 1613 - K-Graph Oddity
查看>>
C# 数字转换成大写
查看>>