您的位置:时时app平台注册网站 > 编程知识 > 【python】-- 多进程的基本语法 、进程间数据交互

【python】-- 多进程的基本语法 、进程间数据交互

2019-10-30 04:21

3.进度和线程之间的分别

  • ### 线程分享地址空间,而经过之间有互相独立的空间

  • ### 线程之间数据互通,相互操作,而经过不得以

  • ### 新的线程比新的历程创建轻巧,比开进度的开销小非常多

  • ### 主线程能够影响子线程,而主进度无法影响子进度

 

 

2、进程中投入线程

from multiprocessing import Process
import time,threading


def thread_run(name):   # 定义线程执行的方法
    print("{0}:{1}".format(name, threading.get_ident()))  # thread.get_ident ()返回当前线程的标识符,标识符是一个非零整数


def run(name):
    time.sleep(2)
    print("hello", name)
    t = threading.Thread(target=thread_run, args=(name,))   # 嵌入线程
    t.start()   # 执行线程


if __name__ == "__main__":
    p_obj_list = list()
    for i in range(10):
        p = Process(target=run, args=("QQ{0}".format(i),))
        p.start()
        p_obj_list.append(p)

    for p in p_obj_list:
        p.join()

 

6.多进度间的通讯和数码分享

率先大家都曾经领会进度之间是独立的,无法互通,并且数据交互独立,而在实际费用中,一定会胜过供给进程间通讯的境况供给,那么大家怎么搞呢

有几种方法:

  • pipe
  • queue

1)使用queue通信

在八十八线程这里已经学过queue了,创制queue的方法,q = queue.Queue(),这种创造是创办的线程queue,实际不是进程queue。成立进程queue的法子是:

时时app平台注册网站 1

 

 

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing

def func(q,name,age): #这里必须要把q对象作为参数传入才能实现进程之间通信
    q.put({'name':name,'age':age})

if __name__ == '__main__':
    q = multiprocessing.Queue() #创建进程queue对象
    ml = []
    for i in range(3):
        p = multiprocessing.Process(target=func,args=(q,'yang',21))
        p.start()
        ml.append(p)
    print(q.get()) #获取queue信息
    print(q.get()) 
    print(q.get())
    for i in ml:
        i.join()

  

运营结果:

时时app平台注册网站 2

 

好的,已经经过queue完成通讯,那么留心的相爱的人可能会想,当时的queue到底是同多个吧如故copy的啊?带头测量试验,码如下:

 

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing

def func(q,name,age):
    q.put({'name':name,'age':age})
    print('id:',id(q))
if __name__ == '__main__':
    q = multiprocessing.Queue()
    ml = []
    print('id:',id(q))
    for i in range(3):
        p = multiprocessing.Process(target=func,args=(q,'yang',21))
        p.start()
        ml.append(p)
    print(q.get())
    print(q.get())
    print(q.get())
    for i in ml:
        i.join()

  

在Windows平台运维结果:

时时app平台注册网站 3

 

Linux的ubuntu下是那样的:

时时app平台注册网站 4

 

那就倒霉怎么说了,我个人的驾驭,线程和经过那类与Computer硬件(CPU,RAM)等有联系的都有不鲜明因素,姑且感觉在Windows平台里queue是copy的,在Linux里是同一个呢,而且据经验职员表示,在macbook上也是同二个。

 

还应该有个难题, 要是使用的queue是线程式的啊?

代码其余都没变,只改了那边:

时时app平台注册网站 5

 

结果:

时时app平台注册网站 6

 

尽管如此报错了,不过却有二个关键点,提醒的是不能够pickle线程锁对象,也正是说刚才我们采取的queue是经过对象,所以可以pickle,注意了,这里就是关键点,使用了pickle,那么也正是说,在Windows平台里是copy的,假设不是copy,就无需存在pickle对吗?直接拿来用正是呀,干嘛要pickle之后取的时候再反pickle呢对啊?

 

再看Linux下呢,由于Linux默许是python2,所以模块包名稍稍有一点不相同

时时app平台注册网站 7

结果阻塞住了,不过前面包车型大巴可能出来了,看到的id果然仍旧长久以来的。

 

那边就有三点须求注意:(个人理解,如有误望指正)

1.进程里的确不可能使用线程式queue

2.Windows平台的进度式queue是copy的

3.Linux平台的线程式和进程式都以同四个,可是如果在经过里使用线程式queue会阻塞住

但作者个人以为copy更有安全性

 

2)使用pipe通信

 

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing

def func(conn):
    conn.send('约吗?')  #子进程发送数据
    print(conn.recv())  #接受数据,不能加参数1024之类的
    conn.close()        #子进程关闭连接
if __name__ == '__main__':
    parent_conn,son_conn = multiprocessing.Pipe() #创建pipe对象,父进程,子进程
    ml = []
    p = multiprocessing.Process(target=func,args=(son_conn,))
    p.start()
    print(parent_conn.recv())  #父进程接受数据,不能加参数1024之类的
    parent_conn.send('不约')    #发送数据
    p.join()                   #join方法是进程特有

 

  

运转结果:

时时app平台注册网站 8

 

如此那般就联系上了,相信你发掘了,基本和前面包车型大巴socket大致,可是唯大器晚成的例外是recv()方法无法加参数,不相信的话,你加来尝试

回望线程通讯,相信您会以为进度比线程更有益于

 

本来pipe也得以有多个:

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing,time

def func(conn):
    conn.send('约吗?')  #子进程发送数据
    print(conn.recv())
    conn.close()        #子进程关闭连接
if __name__ == '__main__':
    parent_conn,son_conn = multiprocessing.Pipe() #创建pipe对象,父进程,子进程
    ml = []
    for i in range(3):
        p = multiprocessing.Process(target=func,args=(son_conn,))
        p.start()
        ml.append(p)
        print(parent_conn.recv())  #父进程接受数据,不能加参数1024之类的
        parent_conn.send('不约')
    for i in ml:
        i.join()

  

运维结果:

时时app平台注册网站 9

 

7.经过之间数据分享——manager

比较轻便,就使用了经过里的manager对象下的各种数据类型,其余的很简短的,作者就不注释了

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing

def func(l,d,num):
    l.append(num)
    d[num] = num

if __name__ == '__main__':
    with multiprocessing.Manager() as manager:
        l = manager.list()
        d = manager.dict()
        ml = []
        for i in range(6):
            p = multiprocessing.Process(target=func,args=(l,d,i))
            p.start()
            ml.append(p)
        for i in ml:
            i.join()
        print('d:',d)
        print('l:',l)

  

运转结果:

时时app平台注册网站 10

 

那样是或不是就达成了数额分享了?

 

好的,进度也分析完了

 

 

时时app平台注册网站 11

 

经过锁和进度池的利用

下边函数通过multiprocessing的queue来完成进程间通讯。

5.回顾实例

1)创制七个简单易行的多进程:

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing,time

def func(name):
    time.sleep(1)
    print('hello',name,time.ctime())

ml = []
for i in range(3):
    p = multiprocessing.Process(target=func,args=('yang',))
    p.start()
    ml.append(p)

for i in ml:
    i.join() #注意这里,进程必须加join方法,不然会导致僵尸进程

  

运营结果:

时时app平台注册网站 12

 

不管怎么说,反正报错了,相通的代码,在python自带的IDLE里索求:

时时app平台注册网站 13

并未有别的东西就终止了。好的,这里要说下了,依据本人个人的知道,当您用pycharm或然IDLE时,pycharm也许IDLE在你的管理器里本人也是四个进程,並且私下认可是主进程。所以在pycharm会报错,而在IDLE里运维正是空白,个人明白,对不对一时不谈,中期学到子进度时再说。

 

消除办法正是,别的的不改变,加叁个if __name == '__main__'判别就行:

时时app平台注册网站 14

 

那般就一蹴而就了,好的,你今后能够体会到那句话了,过程与线程的用法就只是名字差异,使用的章程也是没多大分别。相当少说,自行体会。而运作结果来看的时刻是一路的,那么那进程才是真正含义上的互动运营。

 

2)自定义类式进程

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing,time

class myprocess(multiprocessing.Process):
    def __init__(self,name):
        super(myprocess,self).__init__()
        self.name = name

    def run(self):
        time.sleep(1)
        print('hello',self.name,time.ctime())

if __name__ == '__main__':
    ml = []
    for i in range(3):
        p = myprocess('yang')
        p.start()
        ml.append(p)

    for j in ml:
        j.join()

  

运行结果:

时时app平台注册网站 15

 

 

然后setDaemon之类的不二秘诀和线程也是完全生龙活虎致的。

 

3)每一个历程都有根进度,换句话,每三个进度都有父进度

#!usr/bin/env python
#-*- coding:utf-8 -*-

# author:yangva

import multiprocessing,time,os

def info():
    print('mudule name:',__name__)
    print('parent process:',os.getppid()) #父进程号
    print('son process:',os.getpid())     #子进程号

if __name__ == '__main__':
    info()
    print('-----')
    p = multiprocessing.Process(target=info,args=[])
    p.start()
    p.join()

  

运转结果:

 

时时app平台注册网站 16

 

而查看本人本机的进程:

时时app平台注册网站 17

 

可知,6204正是pycharm,正是此时的根进程,而主进度正是自己这一个py文件(由__main__能够),接着再往下的子进度等等等的。

 

3、老爹和儿子进度

各类子进度都以由多少个父进度运维的,各个程序也许有二个父进程

from multiprocessing import Process
import os


def info(title):
    print(title)
    print('module name:', __name__)
    print('parent process:', os.getppid())  # 获得父进程ID
    print('process id:', os.getpid())  # 获得子进程ID
    print("nn")


def f(name):
    info('\033[31;1m function f\033[0m')
    print('hello', name)

if __name__ == '__main__':
    info('\033[32;1m main process line\033[0m')
    p = Process(target=f, args=('QQ',))
    p.start()
    p.join()

  

 

 

地方代码通过Pipe来得以完结五个进度间的通讯。

4.在python中,进度与线程的用法就只是名字分歧,使用的议程也是没多大分别

进程间数据交互与分享

知道区别进度之间内部存款和储蓄器是不分享的,要想完结七个进度间的通讯须求选用multiprocessing库中的queue(队列)模块,那些multiprocessing库中的queue模块跟单纯的queue库是不相符的。进度导入前面三个(这里的queue是专程为经过之间的通信设计的)不不可信赖,导入前者(这里的queue首借使线程间数据交互)出错。

时时app平台注册网站 18

1.含义:Computer中的程序关于某数码集结上的三回运转活动,是系统举行财富分配和调节的主干单位。说白了正是三个顺序的实践实例。

奉行三个前后相继正是一个经过,比方您张开浏览器看见本人的博客,浏览器本身是一个软件程序,你那时候开垦的浏览器正是一个进程。

 

2、进程访谈queue

from multiprocessing import Process
import queue


def f(q):
    q.put([66, None, 'hello word'])

if __name__ == '__main__':
    q = queue.Queue()   # 把这个q传给了子线程
    p = Process(target=f, args=(q,))   # 子线程访问父线程的q
    p.start()
    print(q.get())
    p.join()

#执行结果
Traceback (most recent call last):
  File "C:/Users/dell/PycharmProjects/untitled/process/进程的定义.py", line 77, in <module>
    p.start()
  File "C:Python36libmultiprocessingprocess.py", line 105, in start
    self._popen = self._Popen(self)
  File "C:Python36libmultiprocessingcontext.py", line 223, in _Popen
    return _default_context.get_context().Process._Popen(process_obj)
  File "C:Python36libmultiprocessingcontext.py", line 322, in _Popen
    return Popen(process_obj)
  File "C:Python36libmultiprocessingpopen_spawn_win32.py", line 65, in __init__
    reduction.dump(process_obj, to_child)
  File "C:Python36libmultiprocessingreduction.py", line 60, in dump
    ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects

下面代码通过gevent模块来落实写成的IO时期活动切换实现产出的程序。
gevent需要从pycharm下载。

进程

3、进度访问`multiprocessing库中的Queue模块`

from multiprocessing import Process,Queue


def f(q):
    q.put([66, None, 'hello word'])

if __name__ == '__main__':
    q = Queue()   # 把这个q传给了子线程
    p = Process(target=f, args=(q,))   # 子线程访问父线程的q
    p.start()
    print(q.get())
    p.join()

#执行结果
[66, None, 'hello word']

父进程相当于克隆一个Q,把团结的Q克隆了风流罗曼蒂克份交给子进度,子进度那时候往Q里面放了风华正茂份数据,然后父进度又能实际的获得到。可是你克隆了生龙活虎份是还是不是就和父进度未有关系了,为何还是可以够维系在一块吧?然而实际上:等于这四个Q里面包车型客车数额又把它种类化了,种类化到叁此中等的地点,肖似于翻译,然后反体系化给那些父进程那边来了,其实那八个Q正是透过pickle来类别化的,不是三个真的的Q。

小结:三个线程之间能够修改四个多少,不加锁,恐怕就能出错。现在历程中的Queue,是兑现了数额的传递,不是在改过同生机勃勃份数据,只是实现三个进度的数额传给了别的贰个经过。

上海体育场合是用yield达成了三个多个函数逇并发管理。

2.进度的风味

  • ### 贰个历程里能够有多个子进程

  • ### 新的进程的成立是全然拷贝整个主进程

  • ### 进程里能够包含线程

  • ### 进度之间(富含主进度和子进度)不设有多中国少年共产党享,相互通讯(浏览器和python之间的数额无法互通的),要通讯则要借助队列,管道之类的

 

2、进程池apply和apply_saync

2.1、appley

同步施行,也等于串行奉行的

from multiprocessing import Pool  # 导入进程池模块pool
import time,os


def foo(i):
    time.sleep(2)
    print("in process", os.getpid())  # 打印进程号


if __name__ == "__main__":
    pool = Pool(processes=5)   # 设置进程池个数为5,也可以写成pool = Pool(5),允许进程池同时放入5个进程,并且这5个进程交给cpu去运行
    for i in range(10):
        pool.apply(func=foo, args=(i,))   # 同步执行挂起进程
    print('end')
    pool.close()
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

2.2、apply_saync

异步实施,也正是并行奉行。

from multiprocessing import Pool  # 导入进程池模块pool
import time,os


def foo(i):
    time.sleep(2)
    print("in process", os.getpid())  # 打印进程号


if __name__ == "__main__":
    pool = Pool(processes=5)   # 设置进程池个数为5,也可以写成pool = Pool(5),允许进程池同时放入5个进程,并且这5个进程交给cpu去运行
    for i in range(10):
        pool.apply_async(func=foo, args=(i,))   # 采用异步方式执行foo函数
    print('end')
    pool.close()
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

2.3、异步下回调函数

程序履行完成之后,再回调过来实施那一个Bar函数。

from multiprocessing import Process,Pool
import time,os


def foo(i):
    time.sleep(2)
    print("in process", os.getpid())  # 打印子进程的进程号


def bar(arg):
    print('-->exec done:', arg, os.getpid())   # 打印进程号

if __name__ == "__main__":
    pool = Pool(processes=2)
    print("主进程", os.getpid())   # 主进程的进程号
    for i in range(3):
        pool.apply_async(func=foo, args=(i,), callback=bar)   # 执行回调函数callback=Bar
    print('end')
    pool.close()
    pool.join()  # 进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。

#执行结果
主进程 752
end
in process 2348
-->exec done: None 752
in process 8364
-->exec done: None 752
in process 2348
-->exec done: None 752

注:

  1. 回调函数表达fun=Foo干不完就不推行bar函数,等Foo实践完就去履行Bar
  2. 其一次调函数是主进度去调用的,并不是各样子进度去调用的。
  3. 回调函数的用处:

      举个例子说你从各类机器上备份完成,在回调函数中自动写贰个剧本,说备份实现

  4. 回调函数是主进程调用的原委?

      若是是子进度去调用这么些回调函数,有稍许个子进度就有稍许个三番四遍,假设是主进度的话,只须求贰次长连接就能够了,这几个频率就高了

  

 

 1 from multiprocessing import  Pipe,Process
 2 def foo(sk):
 3     sk.send('hello world')#通过管道sk发送内容
 4     print(sk.recv())#打印接收到的内容
 5 if __name__ == '__main__':
 6     sock,conn=Pipe()#定义一个管道的两头
 7     p=Process(target=foo,args=(sock,))#由于上面已经通过multiprocessing导入了Process,
 8     # 所以这里直接就可以创建一个子进程,并将sock(管道的一头)作为参数给foo函数
 9     p.start()#激活这个进程
10     print(conn.recv())#打印接收到的内容,conn是管道的另一头
11     conn.send('hi son')#通过管道发送内容

多进程

进程之间是互相独立的,python是开发银行进度的时候,是开发银行的是原生进度。进度是未曾GIL锁的,并且不设有锁的定义,进程之间的数据式不能够分享的,而线程是足以的。

协程
协程,又叫微线程,实际上正是单线程,通过python语法,或模块来贯彻产出。
精气神上正是多少个经过七个线程。

1、进程锁

经过multiprocessing中的Lock模块来促成进程锁

from multiprocessing import Process,Lock   # 导入进程锁


def f(l, i):
    l.acquire()    # 加锁
    try:
        print("hello word", i)
    finally:
        l.release()   # 释放锁

if __name__ == "__main__":
    lock = Lock()     # 定义锁
    for num in range(10):
        Process(target=f, args=(lock, num,)).start()  # 把锁传入进程中

经过中不是互相独立的吗?为何还要加锁:尽管各样进程皆以单独运转的,然则难点来了,它们分享一块荧屏。那几个锁存在的意义正是荧屏分享。若是经过1想着打字与印刷数据,而经过2想也想打字与印刷数据的景况,就有异常的大恐怕乱套了,然后经过这些锁来支配,去打字与印刷的时候,那些显示屏唯有本人独自占领,导致显示器不会乱。

 

1、进度的概念

用muliprocessing那一个包中的Process来定义多进度,跟定义三十多线程相仿

from multiprocessing import Process   # 导入进程模块
import time


def run(name):
    time.sleep(2)
    print("hello", name)

if __name__ == "__main__":
    p_obj_list = list()    # 存放进程对象
    for i in range(10):    # 启动10个进程
        p = Process(target=run, args=("QQ{0}".format(i),))  # 产生一个进程实例
        p.start()   # 启动进程
        p_obj_list.append(p)

    for p in p_obj_list:
        p.join()   # 等待进程结果

时时app平台注册网站 19

【python】-- 多进程的基本语法 、进程间数据交互与共享、进程锁和进程池的使用【时时app平台注册网站】。4、通过Pipe()实现进度间的数据交互,manger实现多中国少年共产党享

下面的例证是因而进度中的Queue,来拓宽数据分享的,其实还会有豆蔻梢头种方法完毕多少分享,那正是管道,pipe,甚至数据分享manger。

4.1、Pipe()函数

管道函数会回来由管道两方接连几日来的生机勃勃组连接对象,该管道暗中认可是双向的(双向的)。

from multiprocessing import Process, Pipe


def f(conn):
    conn.send([66, None, 'hello,word'])  # 发送消息给父进程
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()  # 管道生成返回两个实例,是双向的,这边把第1个作为父连接,第2个作为子连接。也可以,两者角色调换一下
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())   # 接收子进程的消息
    p.join()

4.2、选用一再和殡葬数次

from multiprocessing import Process, Pipe


def f(conn):
    conn.send([66, None, 'hello,word'])  # 发送消息给父进程
    conn.send("QQ")  # 发送消息给父进程
    print(conn.recv())   # 接收父进程的消息
    conn.close()

if __name__ == '__main__':
    parent_conn, child_conn = Pipe()  # 管道生成返回两个实例,是双向的,这边把第1个作为父连接,第2个作为子连接。也可以,两者角色调换一下
    p = Process(target=f, args=(child_conn,))
    p.start()
    print(parent_conn.recv())
    print(parent_conn.recv())  # 接收两次
    parent_conn.send("微信")   # 发送给子进程
    p.join()

4.3、manger

【python】-- 多进程的基本语法 、进程间数据交互与共享、进程锁和进程池的使用【时时app平台注册网站】。manger能够完结数据间的分享。

from multiprocessing import Process, Manager
import os


def f(d, l):
    d[os.getpid()] = os.getpid()
    l.append(os.getpid())
    print(l)

if __name__ == '__main__':
    with Manager() as manager:
        d = manager.dict()   # 声明一个字典,这个字典是用manger声明的,不是用dict()声明的
        # manger.dict()是用专门的语法生产一个可在多进程之间进行传递和共享的一个字典
        l = manager.list(range(5))  # 同样声明一个列表
        p_list = []
        for i in range(10):
            p = Process(target=f, args=(d, l))
            p.start()
            p_list.append(p)
        for res in p_list:
            res.join()
        print(d)
        print(l)

线程纠正同风姿洒脱份数据的时候供给加锁,进程更改数据吧:不用加锁,因为这么些manger已经帮您加锁了,它就暗中认可不允许多个进度同一时间改善风流浪漫份数据。五个进程未有艺术同一时候改过黄金时代份数据,进度之间是独自的,它和睦也要加锁,因为它把自身的东西还要copy好几份,跟刚刚的要命Queue相通,copy十三个字典最后合成多个字典

 

 

时时app平台注册网站, 

地点代码通过Manger完结子进度间的通讯。

1、线程访谈queue

import queue,threading


def f(q):
    q.put([66, None, 'hello word'])

if __name__ == '__main__':
    q = queue.Queue()   # 把这个q传给了子线程
    p = threading.Thread(target=f, args=(q,))   # 子线程访问父线程的q
    p.start()
    print(q.get())
    p.join()

#执行结果
[66, None, 'hello word']

时时app平台注册网站 20

 1 from greenlet import greenlet#导入这个模块
 2 def foo():#定义一个函数
 3     print('ok1')#打印
 4     gr2.switch()#将程序切换到下面一个函数,按照名字切
 5     print('ok3')#打印
 6     gr2.switch()#将程序切换到下面一个函数,按照名字切
 7 def bar():
 8     print('ok2')#打印
 9     gr1.switch()#切到上面foo函数
10     print('ok4')
11 gr1=greenlet(foo)#实例化这个函数
12 gr2=greenlet(bar)
13 gr1.switch()#在外面写这个就执行了这个函数
 1 from multiprocessing import  Manager,Process
 2 def foo(l,i):#收到参数,l是Mlist,i是循环的i
 3     l.append(i*i)#将i平方添加到Mlist
 4 if __name__=='__main__':
 5     manager=Manager()
 6     Mlist=manager.list([11,22,33])#定义一个列表
 7 
 8     l=[]
 9     for i in range(5):#创建5个子进程
10         p=Process(target=foo,args=(Mlist,i))#定义一个进程,将Mlist和i作为参数传到foo
11         p.start()#激活这个进程,执行foo函数
12         l.append(p)#将5个进程添加到l这个列表
13     for i in l:
14         i.join()#循环这个列表,然后将每个进程join
15     print(Mlist)#当所有的子进程都结束,运行主进程

经过greenlet模块的switch来落实协程的切换,greenlet模块供给手动去pycharm下载

 1 import multiprocessing
 2 def foo(q):
 3     q.put([1,'hello',True])
 4 if __name__=='__main__':
 5     q=multiprocessing.Queue()#通过multiprocessing建立一个队列
 6     p=multiprocessing.Process(target=foo,args=(q,))
 7   #用multiprocessing在调用Process,建立一个子进程,定义函数名,将q作为参数传到foo函数,
 8     #foo函数就可以通过这个参数来与主进程做交互了。
 9     p.start()#激活这个子进程
10     print(q.get())#主进程

当三十二线程成立完结之后,start并从未了当下运行,依旧需求和其他线程抢CPU的身价,只是
光阴非常的短。
经过之间的通讯分为二种,queue和pipe

 1 import gevent#导入这个模块
 2 def foo():
 3     print('running in foo')
 4     gevent.sleep(2)#打印之后睡一秒,模拟io操作
 5     print('switch to foo again')
 6 def bar():
 7     print('switch  to bar')
 8     gevent.sleep(1)#打印之后睡一秒,模拟io操作
 9     print('switch to bar again')
10 gevent.joinall([gevent.spawn(foo),gevent.spawn(bar)])
11 '''
12 这个程序的运行过程是,先执行foo函数,
13 打印之后遇到了IO操作,然后自动切换到下一个函数执行,
14 打印之后又遇到了IO操作,然后切回foo函数发现IO2秒还没有结束,
15 然后又切到了bar函数发现IO结束,打印,再切回foo函数打印
16 '''

本文由时时app平台注册网站发布于编程知识,转载请注明出处:【python】-- 多进程的基本语法 、进程间数据交互

关键词: