python

关注公众号 jb51net

关闭
首页 > 脚本专栏 > python > Python多进程Process和管道Pipe的使用

Python多进程Process和管道Pipe的使用方式

作者:AllardZhao

这篇文章主要介绍了Python多进程Process和管道Pipe的使用方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教

如何使用多线程?

实际案例

由于python中全局解释器锁(GIL)的存在,在任意时刻只允许一个线程在解释器中运行。

因此python的多线程不适合处理cpu密集型的任务。

想要处理cpu密集型的任务,可以使用多进程模型。

解决方案

使用标准库中multiprocessing.Process,它可以启动子进程执行任务,操作接口,进程间通信,进程间同步等,都与Threading.Thread类似。

代码演示

(1)进程简单使用

# _*_ encoding:utf-8 _*_
from multiprocessing import Process
 
 
# 定义需要子进程执行函数
def f(s):
    print(s)
 
 
# 创建一个全局变量
x = 1
 
 
# 在f2函数内部修改全局变量的值
def f2():
    # 使用global声明x,然后再修改成5
    global x
    x = 5
 
 
if __name__ == '__main__':
    # 创建子进程执行函数
    p = Process(target=f, args=('hello',))
    # 启动子进程
    p.start()
    # 等待一个进程结束
    p.join()
    '''
    和多线程不一样的是多个进程之间他们使用的虚拟地址空间是独立的。
    '''
    # 在本进程中调用f2,然后查看x发现变成了5
    f2()
    print(x)
    # 将x再修改回去,启动子进程修改
    x = 1
    p1 = Process(target=f2)
    p1.start()
    # 在主进程当中查看x是1还是5
    print(x)
    # 发现x=1,说明子进程和主进程他们看到的,x不是同一个x他们分别是独立的
    # 既然进程之间无法访问彼此的地址空间,进程之间如何通信

(2)Queue队列和Pipe管道的简单使用

# _*_ encoding:utf-8 _*_
from multiprocessing import set_start_method
# 导入进程、队列和管道
from multiprocessing import Process, Queue, Pipe
 
# 注意Queue和queue.Queue并不是同一个对象
q = Queue()
q.put(1)
print(q.get())
 
 
def f(q1):
    print('start')
    # 等待主进程传入一个值
    print(q1.get())
    print('end')
 
 
# Pipe会创建双向的管道
c1, c2 = Pipe()
# 向管道的c1端传入数据,在c2端读取出来
c1.send('abc')
print(c2.recv())
# c2端写入的,从c1端读取出来
c2.send('xyz')
print(c1.recv())
 
 
def f2(c):
    # 从连接中读取数据,然后乘2再写回去
    c.send(c.recv() * 2)
 
 
if __name__ == '__main__':
    '''
    set_start_method为创建进程的方式:
        fork为分支创建,spawn为分产创建。
    '''
    set_start_method('fork', True)
    # ------------------------------
    q2 = Queue()
    # 启动一个子进程直接运行
    Process(target=f, args=(q2,)).start()
    # 子进程阻塞到get,等待传入一个值
    q2.put(100)
    # ------------------------------
    c3, c4 = Pipe()
    # 子进程会等待向管道写
    Process(target=f2, args=(c4,)).start()
    # 从c3端写入数据,然后函数回返回回来,再在c3端读取
    c3.send(55)
    print(c3.recv())

总结

以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。

您可能感兴趣的文章:
阅读全文