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

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

同步锁

import  time, threadingdef addNum():    global num    num -= 1num = 100thread_list = []for i in range(100):    t = threading.Thread(target=addNum)    t.start()    thread_list.append(t)for t in thread_list:    t.join()print('final num:', num)运行结果:final num: 0
import  time, threadingdef addNum():    global num    #num -= 1    tmp = num    time.sleep(0.00001)    num = tmp - 1num = 100thread_list = []for i in range(100):    t = threading.Thread(target=addNum)    t.start()    thread_list.append(t)for t in thread_list:    t.join()print('final num:', num)运行结果:final num: 93 或final num: 91或final num: 94

原因:

第一个程序中,num -= 1 这种写法,程序执行动作太快(完成这个动作在 cup 切换的时间内)
第二个程序中,把 num -= 1 , 加入了 sleep 时间,100个线程存在没有执行完就进行了切换,导致全局的 num 没有正常返回。引用下大神的图发现总结得非常好:
1334255-20180728121100377-823228028.png
在上面的例子中 使用 join 方法会把整个线程停住,造成了串行,失去了多线程的意义,我们只需要在涉及到计算公共数据的时候串行执行即可。

使用同步锁处理计算公共的数据

import  time, threadingdef addNum():    global num    lock.acquire()    tmp = num    time.sleep(0.00001)    num = tmp - 1    lock.release()num = 100lock = threading.Lock()thread_list = []for i in range(100):    t = threading.Thread(target=addNum)    t.start()    thread_list.append(t)for t in thread_list:    t.join()print('final num:', num)运算结果:final num: 0

线程死锁和递归锁

import  threading, timeclass myThread(threading.Thread):    def doA(self):        lockA.acquire()        print(self.name, "gotlockA", time.ctime())        time.sleep(3)        lockB.acquire()        print(self.name, "gotlockB", time.ctime())        lockB.release()        lockA.release()    def doB(self):        lockB.acquire()        print(self.name, "gotlockB", time.ctime())        time.sleep(2)        lockA.acquire()        print(self.name, "gotlockA", time.ctime())        lockA.release()        lockB.release()    def run(self):        self.doA()        self.doB()if __name__ == '__main__':    lockA = threading.Lock()    lockB = threading.Lock()    threads = []    for i in range(5):        threads.append(myThread())    for t in threads:        t.start()    for t in threads:        t.join()#运行结果:Thread-1 gotlockA Sat Jul 28 15:09:31 2018Thread-1 gotlockB Sat Jul 28 15:09:34 2018Thread-1 gotlockB Sat Jul 28 15:09:34 2018Thread-2 gotlockA Sat Jul 28 15:09:34 2018

使用递归锁

import  threading, timeclass myThread(threading.Thread):    def doA(self):        lock.acquire()        print(self.name, "gotlockA", time.ctime())        time.sleep(3)        lock.acquire()        print(self.name, "gotlockB", time.ctime())        lock.release()        lock.release()    def doB(self):        lock.acquire()        print(self.name, "gotlockB", time.ctime())        time.sleep(2)        lock.acquire()        print(self.name, "gotlockA", time.ctime())        lock.release()        lock.release()    def run(self):        self.doA()        self.doB()if __name__ == '__main__':    lock = threading.RLock()    threads = []    for i in range(5):        threads.append(myThread())    for t in threads:        t.start()    for t in threads:        t.join()运行结果:Thread-1 gotlockA Sat Jul 28 15:19:35 2018Thread-1 gotlockB Sat Jul 28 15:19:38 2018Thread-1 gotlockB Sat Jul 28 15:19:38 2018Thread-1 gotlockA Sat Jul 28 15:19:40 2018Thread-3 gotlockA Sat Jul 28 15:19:40 2018Thread-3 gotlockB Sat Jul 28 15:19:43 2018Thread-3 gotlockB Sat Jul 28 15:19:43 2018Thread-3 gotlockA Sat Jul 28 15:19:45 2018Thread-5 gotlockA Sat Jul 28 15:19:45 2018Thread-5 gotlockB Sat Jul 28 15:19:48 2018Thread-5 gotlockB Sat Jul 28 15:19:48 2018Thread-5 gotlockA Sat Jul 28 15:19:50 2018Thread-4 gotlockA Sat Jul 28 15:19:50 2018Thread-4 gotlockB Sat Jul 28 15:19:53 2018Thread-4 gotlockB Sat Jul 28 15:19:53 2018Thread-4 gotlockA Sat Jul 28 15:19:55 2018Thread-2 gotlockA Sat Jul 28 15:19:55 2018Thread-2 gotlockB Sat Jul 28 15:19:58 2018Thread-2 gotlockB Sat Jul 28 15:19:58 2018Thread-2 gotlockA Sat Jul 28 15:20:00 2018

信号量

信号量用来控制线程并发数的,BoundedSemaphore或Semaphore管理一个内置的计数 器,每当调用acquire()时-1,调用release()时+1,计数器不能小于0,当计数器为 0时,acquire()将阻塞线程至同步锁定状态,直到其他线程调用release()。(类似于停车位的概念)。

BoundedSemaphore与Semaphore的唯一区别在于前者将在调用release()时检查计数 器的值是否超过了计数器的初始值,如果超过了将抛出一个异常。

import threading, timeclass myThread(threading.Thread):    def run(self):        if semaphore.acquire():            print(self.name)            time.sleep(5)            semaphore.release()if __name__ == "__main__":    semaphore = threading.Semaphore(5)    thrs = []    for i in range(20):        thrs.append(myThread())    for t in thrs:        t.start()#运行结果:Thread-1Thread-2Thread-3Thread-4Thread-5Thread-6Thread-7Thread-9Thread-10Thread-8Thread-11Thread-13Thread-14Thread-12Thread-15Thread-18Thread-16Thread-17Thread-19Thread-20
import threading, timeclass myThread(threading.Thread):    def run(self):        if semaphore.acquire():            print(self.name)            time.sleep(5)            semaphore.release()if __name__ == "__main__":    semaphore = threading.BoundedSemaphore(5)    thrs = []    for i in range(20):        thrs.append(myThread())    for t in thrs:        t.start()#运行结果:Thread-1Thread-2Thread-3Thread-4Thread-5Thread-6Thread-8Thread-10Thread-9Thread-7Thread-12Thread-14Thread-15Thread-13Thread-11Thread-16Thread-17Thread-20Thread-19Thread-18

转载于:https://www.cnblogs.com/klvchen/p/9381511.html

你可能感兴趣的文章
python之路--day23--面向对象高级
查看>>
azkaban用户管理及权限配置
查看>>
GCD学习笔记
查看>>
[转]Asp.net MVC中的ViewData与ViewBag
查看>>
PHP......会话控制SESSION与COOKIE
查看>>
[转]AchartEngineActivity引擎绘制柱状图、曲线图
查看>>
[转]javascript实现限制上传文件的大小
查看>>
PowerDesigner导出表到word
查看>>
使用 string 的一些规则
查看>>
gnome-terminal的一些调整
查看>>
国内的黄金及现货黄金交易所
查看>>
建站手册-网站主机:主机性能
查看>>
DM9000驱动移植在mini2440(linux2.6.29)和FS4412(linux3.14.78)上的实现(deep dive)篇一
查看>>
电路分析
查看>>
unity开源移动库iTween使用完整Demo
查看>>
QT动态库和静态库使用
查看>>
Kali Linux安装
查看>>
抓取阻塞信息
查看>>
实验三
查看>>
Mysql优化配置
查看>>