01、多线程中queue队列通信方式直接用于多进程报错 -- 不能使用 from queue import Queue
import time
from multiprocessing import Process
from queue import Queue
"""
这个是为了说明:多线程中的queue通信方式直接使用到多进程中会导致错误
############## 报错如下 ##############
TypeError: cannot pickle '_thread.lock' object
source_process = _winapi.OpenProcess(
OSError: [WinError 87] 参数错误。
"""
# 通过队列通信
def producer(queue):
queue.put("a")
time.sleep(2)
def comsumer(queue):
time.sleep(2)
data = queue.get()
print(data)
if __name__ == "__main__":
# 定义队列容量
queue = Queue(10)
# 创建两个进程,传入队列相当于两个进程之间建立了通道|共享内存空间
my_producer = Process(target=producer, args=(queue,))
my_comsumer = Process(target=comsumer, args=(queue,))
# 启动进程
my_producer.start()
my_comsumer.start()
# 阻塞进程
my_producer.join()
my_comsumer.join()
02、多进程使用 queue队列通信方式示例 -- 是用自带的 from multiprocessing import Process, Queue
import time
from multiprocessing import Process,Queue
"""
使用自带的 multiprocessing.Process 和 multiprocessing.Queue模块实现进程间通信
################# 输出结果 #################
a
"""
# 通过队列通信
def producer(queue):
queue.put("a")
time.sleep(2)
def comsumer(queue):
time.sleep(2)
data = queue.get()
print(data)
if __name__ == "__main__":
# 定义队列容量
queue = Queue(10)
# 创建两个进程,传入队列相当于两个进程之间建立了通道|共享内存空间
my_producer = Process(target=producer, args=(queue,))
my_comsumer = Process(target=comsumer, args=(queue,))
# 启动进程
my_producer.start()
my_comsumer.start()
# 阻塞进程
my_producer.join()
my_comsumer.join()
03、共享全局变量的方式,实现进程间通信的思路测试结果 -- 记住共享变量不适用于多进程通信,因为进程间有独立的内存空间
import time
from multiprocessing import Process,Queue
"""
共享全局变量方式测试
################## 输出结果 ###################
1 不是 101,因为变量无法共享
"""
# 通过队列通信
def producer(a):
a += 100
time.sleep(2)
def comsumer(a):
time.sleep(2)
print(a)
if __name__ == "__main__":
# 定义队列容量
a = 1
# 创建两个进程,传入队列相当于两个进程之间建立了通道|共享内存空间
my_producer = Process(target=producer, args=(a,))
my_comsumer = Process(target=comsumer, args=(a,))
# 启动进程
my_producer.start()
my_comsumer.start()
# 阻塞进程
my_producer.join()
my_comsumer.join()
04、multiprocessing中自带的Queue不能用于进程池测试如下:
--上面Queue虽然可以实现进程间通信,但是不能用于进程池中的通信。测试结果如下:
--multiprocessing中Queue不能用于进程池中的代码示例如下:
import time
from multiprocessing import Process, Queue, Pool
"""
multiprocessing中Queue不能用于进程池测试如下:
测试结果就是没有任何输出
"""
# 通过队列通信
def producer(queue):
queue.put("a")
time.sleep(2)
def comsumer(queue):
time.sleep(2)
data = queue.get()
print(data)
if __name__ == "__main__":
# 定义队列容量
queue = Queue(10)
pool = Pool(2)
# 创建两个进程,传入队列相当于两个进程之间建立了通道|共享内存空间
pool.apply_async(producer, args=(queue,))
pool.apply_async(comsumer, args=(queue,))
pool.close()
pool.join()
05、使用 Manager实例化Queue属性方法 进行进程间通信
import time
from multiprocessing import Process, Queue, Pool, Manager
"""
multiprocessing中Queue不能用于进程池测试如下:
"""
# 通过队列通信
def producer(queue):
queue.put("a")
time.sleep(2)
def comsumer(queue):
time.sleep(2)
data = queue.get()
print(data)
if __name__ == "__main__":
# 定义队列容量
queue = Manager().Queue(10)
pool = Pool(2)
# 创建两个进程,传入队列相当于两个进程之间建立了通道|共享内存空间
pool.apply_async(producer, args=(queue,))
pool.apply_async(comsumer, args=(queue,))
pool.close()
pool.join()
06、汇总一下目前学习到的 Queue
from queue import Queue -- 这个用于线程间通信
from multiprocessing import Queue -- 这个用于进程间通信,但不能用于进程池中进程间通信
from multiprocessing import Manager -- 使用Manager()类初始化一个Queue()对象,用于进程池中进程间通信
07、进程间通用:管道 -- Pipe 这个也是仅仅用多个进程间,不能用于进程池,代码示例如下:
--既然已经掌握了队列为什么还需要使用管道:
--队列为了数据同步使用了很多的锁,造成队列性能低于管道pipe
import time
from multiprocessing import Process, Queue, Pool, Manager, Pipe
"""
管道通信最基础方式 -- 进程池中不可用
"""
# 通过队列通信
def producer(pipe):
pipe.send("bobby")
def comsumer(pipe):
print(pipe.recv())
if __name__ == "__main__":
# 建立管道的两端接口
receive_pipe, send_pipe = Pipe()
# 建立两个进程
my_producer = Process(target=producer, args=(send_pipe,))
my_comsumer = Process(target=comsumer, args=(receive_pipe,))
my_producer.start()
my_comsumer.start()
my_producer.join()
my_comsumer.join()
08、进程间通信:使用Manager中的dict() array() list()三种方法实例化相应容器进行进程间变量共享
import time
from multiprocessing import Process, Queue, Pool, Manager, Pipe
"""
multiprocessing中Manager实例化各种容器实现进程间变量共享
############## 输出结果 ###############
{'liming': '25', 'bobby': '23'}
"""
# 通过队列通信
def add_data(p_dict, key, value):
p_dict[key] = value
if __name__ == "__main__":
# 建立管道的两端接口
process_dict = Manager().dict()
# 建立两个进程
first_process = Process(target=add_data, args=(process_dict, "bobby", "23"))
second_process = Process(target=add_data, args=(process_dict, "liming", "25"))
first_process.start()
second_process.start()
first_process.join()
second_process.join()
print(process_dict)