python线程间通信的问题,回答有加分!300
在2.6才开始使用
multiprocessing 是一个使用方法类似threading模块的进程模块。允许程序员做并行开发。并且可以在UNIX和Windows下运行。
通过创建一个Process 类型并且通过调用call()方法spawn一个进程。
一个比较简单的例子:
#!/usr/bin/env python
from multiprocessing import Process
import time
def f(name):
time.sleep(1)
print 'hello ',name
print os.getppid() #取得父进程ID
print os.getpid() #取得进程ID
process_list = []
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
进程间通信:
有两种主要的方式:Queue、Pipe
1- Queue类几乎就是Queue.Queue的复制,示例:
#!/usr/bin/env python
from multiprocessing import Process,Queue
import time
def f(name):
time.sleep(1)
q.put(['hello'+str(name)])
process_list = []
q = Queue()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
for i in range(10):
print q.get()
2- Pipe 管道
#!/usr/bin/env python
from multiprocessing import Process,Pipe
import time
import os
def f(conn,name):
time.sleep(1)
conn.send(['hello'+str(name)])
print os.getppid(),'-----------',os.getpid()
process_list = []
parent_conn,child_conn = Pipe()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(child_conn,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
for p in range(10):
print parent_conn.recv()
Pipe()返回两个连接类,代表两个方向。如果两个进程在管道的两边同时读或同时写,会有可能造成corruption.
进程间同步
multiprocessing contains equivalents of all the synchronization primitives from threading.
例如,可以加一个锁,以使某一时刻只有一个进程print
#!/usr/bin/env python
from multiprocessing import Process,Lock
import time
import os
def f(name):
lock.acquire()
time.sleep(1)
print 'hello--'+str(name)
print os.getppid(),'-----------',os.getpid()
lock.release()
process_list = []
lock = Lock()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
进程间共享状态 Sharing state between processes
当然尽最大可能防止使用共享状态,但最终有可能会使用到.
1-共享内存
可以通过使用Value或者Array把数据存储在一个共享的内存表中
#!/usr/bin/env python
from multiprocessing import Process,Value,Array
import time
import os
def f(n,a,name):
time.sleep(1)
n.value = name * name
for i in range(len(a)):
a[i] = -i
process_list = []
if __name__ == '__main__':
num = Value('d',0.0)
arr = Array('i',range(10))
for i in range(10):
p = Process(target=f,args=(num,arr,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print num.value
print arr[:]
输出:
jimin@Jimin:~/projects$ python pp.py
81.0
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
'd'和'i'参数是num和arr用来设置类型,d表示一个双精浮点类型,i表示一个带符号的整型。
更加灵活的共享内存可以使用multiprocessing.sharectypes模块
Server process
Manager()返回一个manager类型,控制一个server process,可以允许其它进程通过代理复制一些python objects
支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array
例如:
#!/usr/bin/env python
from multiprocessing import Process,Manager
import time
import os
def f(d,name):
time.sleep(1)
d[name] = name * name
print d
process_list = []
if __name__ == '__main__':
manager = Manager()
d = manager.dict()
for i in range(10):
p = Process(target=f,args=(d,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print d
输出结果:
{2: 4}
{2: 4, 3: 9}
{2: 4, 3: 9, 4: 16}
{1: 1, 2: 4, 3: 9, 4: 16}
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 8: 64}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
Server process managers比共享内存方法更加的灵活,一个单独的manager可以被同一网络的不同计算机的多个进程共享。
比共享内存更加的缓慢
使用工作池 Using a pool of workers
Pool类代表 a pool of worker processes.
It has methods which allows tasks to be offloaded to the worker processes in a few different ways.
正常的做法是在打印的时候加一个串口的标识做输出字符串的前缀, 比如:
serial 1: xxxx
serial 2: yyyy
这样是不需要用两个窗口的,如果一定要两个窗口,那建议使用GUI程序来做。
pyqt的线程之间的通信是通过信号to槽来实现的,首先你在线程类里面声明一个全局槽比如:
class imThread(QtCore.QThread):
imslot = QtCore.pyqtSignal()
这里是要重点注意,上面的是没有任何参数的一个信号,如果你需要参数的话,你可以在里面添加参数类型,例如:
imslot1 = QtCore.pyqtSignal(str) #这是一个带字符串参数的信号
imslot2 = QtCore.pyqtSignal(int) #这是一个带整型参数的信号
imslot3 = QtCore.pyqtSignal(bool) #这是一个带布尔参数的信号
当然了,如果你需要多个参数的话,同样地往里面加就是了,qt也没有要求参数必须是同类型的,所以可以这样:
imslot1 = QtCore.pyqtSignal(str, int) #这是一个带整型和字符串的参数信号
imslot2 = QtCore.pyqtSignal(int, str, str) #这是一个带整型和两个字符串的参数信号
imslot3 = QtCore.pyqtSignal(bool, str) #这是一个带布尔和字符串的参数信号
在线程的run方法里面来定义执行信号:
self.imslot.emit()
这里也是需要重点注意的是,上面这个接口是没有参数的,如果你是要参数的话,是需要这样写:
self.imslot1[str].emit('hello')
self.imslot2[int].emit(1)
self.imslot3[bool].emit(False)
多参数的是这样
self.imslot1[str, int].emit('hello', 1)
self.imslot2[int, str, str].emit(1, "hello", "world")
self.imslot3[bool, str].emit(False, 'hello')
以上就是在线程类里面完成信号定义了,接下来就是逻辑层成定义一个函数槽来连接线程类里面的信号,这个也很简单,比如我在主线程类里面定义一个方法:
def imSlot():
print 'ok'
以上这个是槽函数,接下来是实现信号槽的连接
imThread.imslot.connect('imSlot')
这个就是信号槽的连接方式,当然了,这个是没有参数的一个信号槽,那么带参数的怎么写呢?也很简单!首先定义一个槽函数:
def imSlot(para):
print para
这个是带参数的槽函数,下面是:
imThread.imslot[str].connect('imSlot')
以上就是线程之间的方法了,子线程在执行的通行经过执行信号的话,子线程可以安全地执行而不会出现GUI主线程卡死的情况了。
Qt只允许主线程使用界面类,因为界面类不是线程安全的,不可重入,在多个线程中使用可能会出现问题,因此Qt不建议主界面线程外的线程使用图形类和调用图形类接口。建议你修改最初的设计,让界面与控制分离,主线程主要做界面显示,工作线程使用signal-slot控制主线程中的界面类,从而间接达到控制目的。
python多进程和多线程的区别
对主线程的修改可能会影响其他线程的行为,但是父进程的修改(除了删除以外)不会影响其他子进程。线程是一个上下文的执行指令,而进程则是与运算相关的一簇资源。同一个进程的线程之间可以直接通信,但是进程之间的交流需要借助中间代理来实现。创建新的线程很容易,但是创建新的进程需要对父进程做一次复制。
Python中的并行和并发是什么
另外一个进程必须等待其执行完毕,才能继续执行。异步执行:一个进程在执行某个任务时,另外一个进程无需等待其执行完毕,就可以继续执行,当有消息返回时,系统会通知后者进行处理,这样可以提高执行效率。举个例子,打电话时就是同步通信,发短息时就是异步通信。相关推荐:Python如何实现线程间同步 ...
python多线程实现简易 pub\/sub 消息系统
本文介绍python多线程的基础知识,包括线程和进程的概念、常用库、应用场景,并通过实例实现一个简单的pub\/sub系统。多线程是进程的一个执行单元,多个线程共享同一进程的资源。线程之间的切换比进程快,且通信与数据共享更加方便。并发模式下,根据任务类型选择合适的方式:IO等待长的任务适合用多线程优化,...
为什么在python里推荐使用多进程而不是多线程
在Python多线程下,每个线程的执行方式:1、获取GIL 2、执行代码直到sleep或者是python虚拟机将其挂起。3、释放GIL 可见,某个线程想要执行,必须先拿到GIL,我们可以把GIL看作是“通行证”,并且在一个python进程中,GIL只有一个。拿不到通行证的线程,就不允许进入CPU执行。在Python2.x里,GIL的释放...
Python多线程—threading库使用
使用setDaemon(True)方法,可以将子线程设置为守护线程。当主线程结束时,所有守护线程也将自动终止。通过调用join()方法,主线程可以等待所有子线程完成。在同一个进程的多线程之间共享资源,全局变量可以被多个线程访问和修改,但同时修改可能引发数据异常。为解决此问题,引入了线程锁机制,确保同一时刻只有...
为什么有人说 Python 的多线程是鸡肋
多进程稳定,启动时开销大点,但如果你的运行时间远大于多进程的时间,用多进程比较方便,如postgresql用多进程,chrome 多进程。如果你只是想做个定时器样的简单东西,对稳定性要求低些,如vb,c#类似的定时器,用多线程吧,但线程的同步要注意了。python的线程更加类似定时器,python的线程不是真线程,...
python的父线程sleep会导致子线程sleep吗
既然是线程,当然sleep就不会导致另外一个线程阻塞了。父线程只是创建子线程,这种关系而已,没有生死绑定
python多线程的几种方法
详细解释:1. 使用`threading`模块:Python的`threading`模块是最基本的实现多线程编程的方式。通过创建线程对象,可以启动独立的线程执行特定的任务。这种方式简单易用,但需要注意线程间的同步和互斥问题。2. 使用`concurrent.futures`模块:该模块提供了一个高级的接口来管理和调度异步任务。通过`ThreadPool...
【Python进阶】Python并发编程:揭开多线程与异步编程的神秘面纱_百度知 ...
在实践中,I\/O密集型任务适合多线程优化,而CPU密集型则可能需要多进程或异步I\/O配合。concurrent.futures模块简化了多线程编程,如使用ThreadPoolExecutor来调度任务。异步编程,如asyncio,通过非阻塞I\/O和事件循环,提升系统并发能力,尤其在处理高并发场景时效果显著。多进程编程如multiprocessing提供进程间...
如何进行Python多线程编程,一文读懂Python多线程
本文介绍的是Python多线程,想了解Python多线程,得先了解什么是线程。线程是操作系统能够进行运算调度的最小单位。它被包含在进程之中,是进程中的实际运作单位。一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务。而多线程类似于同时执行多个不同程序...
澹砍重组: 多线程通信的方法主要有以下三种: 1.全局变量 进程中的线程间内存共享,这是比较常用的通信方式和交互方式. 注:定义全局变量时最好使用volatile来定义,以防编译器对此变量进行优化. 2.Message消息机制 常用的Message通信的接口主...
长泰县17011599328: 线程间通信有哪些机制 - ?
澹砍重组: 机制?您是问有什么方法么? 1. 可以通过启动线程前传递的 object 对象传递数据(线程启动的时候可以接收一个 object 对象). 2. 通过委托传递数据(大多是子线程操作主线程的时候用到). 3. 通过静态的通用变量或属性传递(建个静态的变量或属性,将要传递的数据写在它上面,然后另一个线程在去这个变量或属性中读取这个值).
长泰县17011599328: 线程间通信有什么手段是跨平台的? - ?
澹砍重组: 线程间不需要通讯机制,只需要同步机制.win32支持命名管道import win32pipewin32pipe.CreateNamedPipe()
长泰县17011599328: 线程间通信有什么手段是跨平台的??
澹砍重组: Python的线程模块不是跨平台的,记得Socket模块也不完全跨平台.可以考虑PyQT4,因为QT是跨平台的,PyQT也是.
长泰县17011599328: 主线程与子线程之间的通信问题 - ?
澹砍重组: 用SendMessage或PostMessage向主线程的主窗体发送自定义消息,在消息处理函数中显示数据 希望对你有所帮助!
长泰县17011599328: python开发之怎样在线程间进行事件通知 - ?
澹砍重组: 展开全部1.等待事件一端调用wait,等待事件 event.wait(),如果要wait持续生效 得event.clear()2.通知事件一端调用set,通知事件 event.set()3.daemon线程是指所有的线程如果结束了,daemon线程也会结束!
长泰县17011599328: python的multiprocessing到底怎么用的问题 - ?
澹砍重组: 众所周知,由于python(Cpython)的全局锁(GIL)问题存在,导致Thread也就是线程的并行并不可实现. multiprocessing 模块采用多进程而不是多线程的方式实现并行,解决了GIL的问题,一定程度上使状况得到了缓解.然而,Multiprocess本身依...
长泰县17011599328: 多线程间怎么传递数据 - ?
澹砍重组: 线程之间数据是没法传递的,但是线程之间是可以通信的,在java中,在同步块中或者同步方法中,使用notify、wait方法可以实现线程的同步与互斥.
长泰县17011599328: Python multiprocessing.Queue 和 Queue有区别吗 - ?
澹砍重组: 觉得这个问题提的好,Queue是python自带的标准库,支持线程安全,所以多线程下可以随意使用,不会出现写冲突.multiprocessing.Queue这个multiprocessing模块封装的,它支持多进程之间的交互,比如master-worker模式下,master进程写入,work进程消费的模式,支持进程之间的通信.如果使用python做比较复杂的情况下,这个模块会经常用到
长泰县17011599328: python3.4.3 多进程之间结果变量的传递问题,程序无任何结果输出 - ?
澹砍重组: 多进程间共享的变量要使用特殊的数据结构,在multiprocessing包里有提供,常用的有Queue, Value, Array等,这里比较适合用Queue 修改后的程序如下,注意Result赋值,和ProcessCheck的参数 另外,Result要排序后输出的话,要用循环从...