互斥锁同时只允许一个线程更改数据,而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
互斥锁和信号量的区别:
- 互斥量用于线程的互斥,信号量用于线程的同步。这是互斥量和信号量的根本区别,也就是互斥和同步之间的区别。
- 互斥:是指某一资源同时只允许一个访问者对其进行访问,具有唯一性和排它性。但互斥无法限制访问者对资源的访问顺序,即访问是无序的。
- 信号:是指在互斥的基础上(大多数情况),通过其它机制实现访问者对资源的有序访问。在大多数情况下,同步已经实现了互斥,特别是所有写入资源的情况必定是互斥的。少数情况是指可以允许多个访问者同时访问资源
- 互斥量值只能为0/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个线程,等前面执行完成后,在进行下一个。最后剩下两个,会一起执行。整个执行过程中是无序的。