12第七周-网络编程 - 线程中的信号量(Semaphore)

Posted chen170615

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了12第七周-网络编程 - 线程中的信号量(Semaphore)相关的知识,希望对你有一定的参考价值。

  

  互斥锁同时只允许一个线程更改数据,而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,time

def 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:
    pass
else:
    print("--all thread done--")
输出:
run the  thread:0
run the  thread:1
run the  thread:2
run the  thread:3
 
run the  thread:4
run the  thread:7
run the  thread:5
run the  thread:6
 
run the  thread:9
run the  thread:8
 
--all thread done--
Process finished with exit code 0

备注:每次执行4个线程,等前面执行完成后,在进行下一个。最后剩下两个,会一起执行。整个执行过程中是无序的。

 

以上是关于12第七周-网络编程 - 线程中的信号量(Semaphore)的主要内容,如果未能解决你的问题,请参考以下文章

6第七周-网络编程-继承式多线程

并发编程——线程

8第七周-网络编程-GIL锁介绍

第七周作业

17第七周-网络编程 - 协程概念介绍协程gevent模块并发爬网页

2019-2020-1学期 20192429 《网络空间安全专业导论》第七周学习总结