博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
并发&并行 同步&异步 GIL 任务 同步锁 死锁 递归锁
阅读量:4350 次
发布时间:2019-06-07

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

# 并发&并行 同步&异步 GIL 任务 同步锁 死锁 递归锁 # 并发:是指系统具有处理多个任务(动作)的能力# 并行:是指系统具有 同时 处理多个任务(动作)的能力# 同步:当进程执行到一个IO(等待外部数据)的时候,需要等待外部数据接收完# 异步:当进程执行到一个IO(等待外部数据)的时候,不需要等待外部数据接收完,还可以做其它的处理# GIL: 全局解释器锁 在python中,无论你启多少个线程,你有多少个cpu,python在执行的时候在同一时刻只请允许一个线程运行# 任务:IO密集型(python的多线程是有意义的,或使用多进程+协程) 计算密集型(python的多线程就不推荐,python就不适用了)# 同步锁import threading, timenum = 100def sub():    global num    temp = num    time.sleep(0.00001)    num = temp - 1l = []  # 定义一个空列表for i in range(100):  # 循环100次    t = threading.Thread(target=sub)  # 通过循环创建100个线程t对象并放入列表中    t.start()    l.append(t)for t in l:  # 循环列表,让每一个线程对象t执行join()    t.join()print(num)  # 99 居然不是0,问题在哪里?# 因为此时是IO操作,当第一个线程取到100后要睡1秒,这时还没有减1,这时第二个线程又来取值,值还是100,只要cpu执行速度越快,所有的线程来取值时都是100,意味着100个线程都拿到num为100# 如果sleep(0.00001),这时最终值又会变为92。这里的值与cpu调度的各线程IO操作的时间有关,sleep时间越短,各个线程拿到num为100时的情况就越少# 解决方法,加上同步锁,在同一时间只允许一个线程对num操作import threading, timenum = 100def sub():    global num    lock.acquire()  # 加锁    temp = num    time.sleep(0.00001)    num = temp - 1    lock.release()  # 解锁l = []  # 定义一个空列表lock = threading.Lock()  # 创建同步锁for i in range(100):  # 循环100次    t = threading.Thread(target=sub)  # 通过循环创建100个线程t对象并放入列表中    t.start()    l.append(t)for t in l:  # 循环列表,让每一个线程对象t执行join()    t.join()print(num)  # 0# 一个死锁的例子 第一个线程需要A锁(A锁已被第二个线程占用),第二个线程需要B锁(B锁已被第一个线程占用)。结果谁也不让造成死锁import threading, timeclass MyThread(threading.Thread):    def actionA(self):        A.acquire()        print(self.name, 'gotA', time.ctime())        time.sleep(2)        B.acquire()        print(self.name, 'gotB', time.ctime())        time.sleep(2)        B.release()        A.release()    def actionB(self):        B.acquire()        print(self.name, 'gotB', time.ctime())        time.sleep(2)        A.acquire()        print(self.name, 'gotA', time.ctime())        time.sleep(2)        A.release()        B.release()    def run(self):        self.actionA()        self.actionB()if __name__ == '__main__':    A = threading.Lock()    B = threading.Lock()    l = []    for i in range(5):        t = MyThread()        t.start()        l.append(t)    for i in l:        t.join()    print('end...')# 解决死锁的方案,使用递归锁import threading, timeclass MyThread(threading.Thread):    def actionA(self):        r_lock.acquire()        print(self.name, 'gotA', time.ctime())        time.sleep(2)        r_lock.acquire()        print(self.name, 'gotB', time.ctime())        time.sleep(2)        r_lock.release()        r_lock.release()    def actionB(self):        r_lock.acquire()        print(self.name, 'gotB', time.ctime())        time.sleep(2)        r_lock.acquire()        print(self.name, 'gotA', time.ctime())        time.sleep(2)        r_lock.release()        r_lock.release()    def run(self):        self.actionA()        self.actionB()if __name__ == '__main__':    r_lock = threading.RLock()  # 这里创建的是递归锁,将原来的两把锁AB换成一把锁    # 哪个线程拿到r_lock锁,只有等它完全释放后,其它的线程才能再拿这个锁    l = []    for i in range(5):        t = MyThread()        t.start()        l.append(t)    for i in l:        t.join()    print('end...')

 

转载于:https://www.cnblogs.com/dangrui0725/p/9496031.html

你可能感兴趣的文章
Arraylist集合遍历输出
查看>>
java中的选择结构与循环结构
查看>>
无法将类型“ASP.login_aspx”转换为“System.Web.UI.WebControls.Login”
查看>>
[cocos2dx] lua注册回调到c++
查看>>
(treap)[bzoj3224][洛谷3369][cogs1829]Tyvj 1728 普通平衡树
查看>>
Linux下常用的shell命令记录
查看>>
HTTP 常用 Header 讲解
查看>>
linux分割字符串操作
查看>>
PHP学习2
查看>>
多实例Mysql配置
查看>>
KOA中间件源码解析
查看>>
Mapnik使用postgres中的栅格数据
查看>>
html基本知识
查看>>
HDU 1599 find the mincost route(floyd求最小环 无向图)
查看>>
Java学习之异常处理
查看>>
combox的DispalyMember和ValueMember属性的测试
查看>>
Start Developing Mac Apps -- Human Interface Design 用户界面设计
查看>>
linux下安装Mongodb
查看>>
Page.RegisterStartupScript和Response.Write的区别。
查看>>
hdu4348区间更新的主席树+标记永久化
查看>>