Python的线程/进程间通讯对象分析
2019独角兽企业重金招聘Python工程师标准>>>
Python提供了一系列的对象支持线程/进程间的通讯:
- Lock
- RLock
- Condition
- Semaphone
- BounderSemaphone
- Event
- Barrier
除了Lock,Rlock外,进程的相关对象只是线程相关对象的clone,而且进程的Lock,RLock也是与线程Lock,RLock相对应的对象。在这里我们只分析线程的这几种对象。
一般使用范围:
Lock用于对互斥操作(单一资源,全局变量)
RLock与Lock类似,区别仅在与RLock在同一个线程可以多次获取
Semaphone/BounderSemaphone用于对多个资源的申请使用, 如果BounderSemaphone(1)则==Lock()
Condition用于在等待某种事情发生
Event实际上是对Condition的一种操作简化包装,也更符合事件驱动的概念。
这几种对象大概使用上面这些对象所要付出的开销是不同的,我们从其原理来进行分析。
from time import sleep
from threading import Thread, Lock
class MyThread(Thread):def __init__(self, name, lock):super(MyThread, self).__init__(name=name)self.lock = lockdef run(self):with self.lock:print('my name is %s, i will sleep 2 seconds' % self.name)sleep(2)print('i wake up now.')if __name__ == '__main__':lock = Lock()mt1 = MyThread('t1', lock)mt2 = MyThread('t2', lock)mt1.start(); mt2.start()mt1.join(); mt2.join()print('main thread end!')
Lock的使用方法参考上面的代码,而RLock是跟Lock的区别是如果在本线程已经acquire,则可以多次acquire,不同线程下则跟Lock是一致的;我们来看一下RLock的实现:
class _RLock:def __init__(self):self._block = _allocate_lock()self._owner = Noneself._count = 0def acquire(self, blocking=True, timeout=-1):me = get_ident() # 获取当前thread的identityif self._owner == me: # 锁的所有者是自己self._count += 1return 1rc = self._block.acquire(blocking, timeout) #获取锁if rc:self._owner = meself._count = 1return rc
从上面的代码可以看出,RLock实际上是使用了Lock,只是在acquire时判断了是否是本线程,如果是,则记录lock次数不做阻塞返回。
而Condition在调用wait时则新生成了一个Lock,并acquire了两次已达到阻塞的目的,而。
class Condition:def __init__(self, lock=None):.....self._waiters = _deque() # 初始化waiter Lock 队列def wait(self, timeout=None):if not self._is_owned(): # 必须要先获取锁raise RuntimeError("cannot wait on un-acquired lock")waiter = _allocate_lock()waiter.acquire()self._waiters.append(waiter) #将waiter Lock加入waiter队列.....waiter.acquire()def _is_owned(self):# Return True if lock is owned by current_thread.# This method is called only if _lock doesn't have _is_owned().if self._lock.acquire(0):self._lock.release() # 在wait,notify时会释放互斥锁return Falseelse:return Truedef notify(self, n=1):if not self._is_owned(): # 必须要先获取锁raise RuntimeError("cannot notify on un-acquired lock")all_waiters = self._waiterswaiters_to_notify = _deque(_islice(all_waiters, n))if not waiters_to_notify:returnfor waiter in waiters_to_notify:waiter.release() #根据通知数量依次释放
Lock只是一个单纯的互斥体,而Condition则可在某种条件发生后主动通知正在等待某种条件的线程。
from threading import Thread, Lock, Conditionclass MyWaitThread(Thread):def __init__(self, name, cond):super(MyWaitThread, self).__init__(name=name)# self.name = nameself.cond = conddef run(self):with self.cond:print('I am waiting something happen!')self.cond.wait()print('wait end!')class MyNotifyThread(Thread):def __init__(self, name, cond):super(MyNotifyThread, self).__init__(name=name)# self.name = nameself.cond = conddef run(self):with self.cond:print('I am notifying all the wait thread.')self.cond.notify_all()print('notify end.')if __name__ == '__main__':cond = Condition()mt1 = MyWaitThread('t1', cond)mt2 = MyWaitThread('t2', cond)mt3 = MyNotifyThread('t3', cond)mt1.start(); mt2.start(); mt3.start()mt1.join(); mt2.join();mt3.join()print('main thread end!')
Semaphone使用Condition的wait,notify来实现,但是却可以看成一个可以在不同线程中同时获取N次的锁。
转载于:https://my.oschina.net/caoxinyu0205/blog/741819
Python的线程/进程间通讯对象分析相关推荐
- python与c进程间通讯_python 与c通信
Python多进程并行编程实践-mpi4py的使用 前言 在高性能计算的项目中我们通常都会使用效率更高的编译型的语言例如C.C++.Fortran等,但是由于Python的灵活性和易用性使得它在发展和 ...
- Python多进程编程-进程间共享 对象
Value.Array是通过共享内存的方式共享数据 Manager是通过共享进程的方式共享数据. 队列直接插入元祖,对象也是可以的:event需要是manager的,这个对象可以在多个进程里面共享 ...
- Python 第八篇:异常处理、Socket语法、SocketServer实现多并发、进程和线程、线程锁、GIL、Event、信号量、进程间通讯...
本节内容: 异常处理.Socket语法.SocketServer实现多并发.进程和线程.线程锁.GIL.Event.信号量.进程间通讯.生产者消费者模型.队列Queue.multiprocess实例 ...
- Python3.5 queue 模块详解 和 进程间通讯
queue - A synchronized queue class:https://docs.python.org/3/library/queue.html 菜鸟教程 - Python3 多线程:h ...
- Android-Binder进程间通讯机制-多图详解
本系列: Android-Binder进程间通讯机制-多图详解 一次Binder通信最大可以传输多大的数据? 关于Binder (AIDL)的 oneway 机制 概述 最近在学习Bin ...
- 管道实现进程间通讯 、WaitNamedPipe
一.管道实现进程间通讯 主要的理论知识 1.什么是管道以及分类 管道是两个头的东西,每一个头各连接一个进程或者同一个进程的不同代码,依照管道的类别分有两种管道,匿名的和命名的:依照管道的传输方向分也能 ...
- WIN32 进程间通讯-共享内存
一.引言 在Windows程序中,各个进程之间常常需要交换数据,进行数据通讯.WIN32 API提供了许多函数使我们能够方便高效的进行进程间的通讯,通过这些函数我们可以控制不同进程间的数据交换 ...
- 一篇文章了解相见恨晚的 Android Binder 进程间通讯机制
概述 最近在学习Binder机制,在网上查阅了大量的资料,也看了老罗的Binder系列的博客和Innost的深入理解Binder系列的博客,都是从底层开始讲的,全是C代码,虽然之前学过C和C++,然而 ...
- 【Linux】-- 进程间通讯
目录 进程间通讯概念的引入 意义(手段) 思维构建 进程间通信方式 管道 站在用户角度-浅度理解管道 匿名管道 pipe函数 站在文件描述符角度-深度理解管道 管道的特点总结 管道的拓展 单机版的负载 ...
最新文章
- netsh命令修改ip
- Quartz 框架快速入门(二)
- python的变量和简单的数据类型
- golang中并发sync和channel
- TCP穿透NAT的C++版
- IBASE archive pre-processing report RIBARCHV
- C++之virtual 方法
- 将太阳光聚集起来可以用来做饭!?
- 2019网络教育计算机统考模拟试题,最新2019年网络远程教育《计算机应用基础》统考模拟题库500题(含答案)...
- 《AFTrans》来自ViT的免费午餐!北大阿里提出用于细粒度视觉识别的自适应注意多尺度融合Transformer...
- JavaScript——闭包函数及拓展题目
- 工作中使用到的单词(软件开发)_2022-02-26_备份
- 开好会议有诀窍------(转)
- 1.7 试探法(回溯法)
- BOOST库介绍(三)——网络编程相关的库
- 微软打击盗版的“三部曲”
- python爬虫之获取谷歌浏览器所有cookie
- git 创库命令使用
- vim方向键、退格键失效,insert模式异常修复方法
- 忘记了MySQL的用户名和密码如何修改