python进程使用Queue和Pipe通信-创新互联

背景

当使用多个线程操作任务的时候,如果线程间有需要通信的地方,那么不可避免的要实现到线程间的通信,来互相通知消息,同步任务的执行。

创新互联建站坚持“要么做到,要么别承诺”的工作理念,服务领域包括:成都网站建设、成都做网站、企业官网、英文网站、手机端网站、网站推广等服务,满足客户于互联网时代的双湖网站设计、移动媒体设计的需求,帮助企业找到有效的互联网解决方案。努力成为您成熟可靠的网络建设合作伙伴!

一.通信

1.线程threading共享内存地址,进程与进程Peocess之间相互独立,互不影响(相当于深拷贝);

2.在线程间通信的时候可以使用Queue模块完成,进程间通信也可以通过Queue完成,但是此Queue并非线程的Queue,进程间通信Queue是将数据 pickle 后传给另一个进程的 Queue,用于父进程与子进程之间的通信或同一父进程的子进程之间通信;

queue

python中的queue模块其实是对数据结构中栈和队列这种数据结构的封装,把抽象的数据结构封装成类的属性和方法

使用Queue线程间通信:

#导入线程相关模块

importthreading

importqueue

q=queue.Queue()

1

2

3

4

5

使用Queue进程间通信,适用于多个进程之间通信:

# 导入进程相关模块

frommultiprocessingimportProcess

frommultiprocessingimportQueue

q=Queue()

1

2

3

4

5

使用Pipe进程间通信,适用于两个进程之间通信(一对一):

# 导入进程相关模块

frommultiprocessingimportProcess

frommultiprocessingimportPipe

pipe=Pipe()

1

2

3

4

5

二.python进程间通信Queue/Pipe使用

python提供了多种进程通信的方式,主要Queue和Pipe这两种方式,Queue用于多个进程间实现通信,Pipe用于两个进程的通信;

1.使用Queue进程间通信,Queue包含两个方法:

  • put():以插入数据到队列中,他还有两个可选参数:blocked和timeout。详情自行百度

  • get():从队列读取并且删除一个元素。同样,他还有两个可选参数:blocked和timeout。详情自行百度

# !usr/bin/env python

# -*- coding:utf-8 _*-

"""

@Author:何以解忧

@Blog(个人博客地址): shuopython.com

@WeChat Official Account(微信公众号):猿说python

@Github:www.github.com

@File:python_process_queue.py

@Time:2019/12/21 21:25

@Motto:不积跬步无以至千里,不积小流无以成江海,程序人生的精彩需要坚持不懈地积累!

"""

frommultiprocessingimportProcess

frommultiprocessingimportQueue

importos,time,random

#写数据进程执行的代码

defproc_write(q,urls):

    print('Process is write....')

    forurlinurls:

        q.put(url)

        print('put %s to queue... '%url)

        time.sleep(random.random())

#读数据进程的代码

defproc_read(q):

    print('Process is reading...')

    whileTrue:

        url=q.get(True)

        print('Get %s from queue'%url)

if__name__=='__main__':

    #父进程创建Queue,并传给各个子进程

    q=Queue()

    proc_write1=Process(target=proc_write,args=(q,['url_1','url_2','url_3']))

    proc_write2=Process(target=proc_write,args=(q,['url_4','url_5','url_6']))

    proc_reader=Process(target=proc_read,args=(q,))

    #启动子进程,写入

    proc_write1.start()

    proc_write2.start()

    proc_reader.start()

    #等待proc_write1结束

    proc_write1.join()

    proc_write2.join()

    #proc_raader进程是死循环,强制结束

    proc_reader.terminate()

    print("mian")

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

输出结果:

Processiswrite....

puturl_1toqueue...

Processiswrite....

puturl_4toqueue...

Processisreading...

Geturl_1fromqueue

Geturl_4fromqueue

puturl_5toqueue...

Geturl_5fromqueue

puturl_2toqueue...

Geturl_2fromqueue

puturl_3toqueue...

Geturl_3fromqueue

puturl_6toqueue...

Geturl_6fromqueue

mian

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

2.使用Pipe进程间通信

Pipe常用于两个进程,两个进程分别位于管道的两端 * Pipe方法返回(conn1,conn2)代表一个管道的两个端,Pipe方法有duplex参数,默认为True,即全双工模式,若为FALSE,conn1只负责接收信息,conn2负责发送,Pipe同样也包含两个方法:

send() : 发送信息;

recv() : 接收信息;

frommultiprocessingimportProcess

frommultiprocessingimportPipe

importos,time,random

#写数据进程执行的代码

defproc_send(pipe,urls):

    #print 'Process is write....'

    forurlinurls:

        print('Process is send :%s'%url)

        pipe.send(url)

        time.sleep(random.random())

#读数据进程的代码

defproc_recv(pipe):

    whileTrue:

        print('Process rev:%s'%pipe.recv())

        time.sleep(random.random())

if__name__=='__main__':

    #父进程创建pipe,并传给各个子进程

    pipe=Pipe()

    p1=Process(target=proc_send,args=(pipe[0],['url_'+str(i)foriinrange(10)]))

    p2=Process(target=proc_recv,args=(pipe[1],))

    #启动子进程,写入

    p1.start()

    p2.start()

    p1.join()

    p2.terminate()

    print("mian")

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

输出结果:

Processissend:url_0

Processrev:url_0

Processissend:url_1

Processrev:url_1

Processissend:url_2

Processrev:url_2

Processissend:url_3

Processrev:url_3

Processissend:url_4

Processrev:url_4

Processissend:url_5

Processissend:url_6

Processissend:url_7

Processrev:url_5

Processissend:url_8

Processissend:url_9

Processrev:url_6

mian

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

三.测试queue.Queue来完成进程间通信能否成功?

当然我们也可以尝试使用线程threading的Queue是否能完成线程间通信,示例代码如下:

frommultiprocessingimportProcess

# from multiprocessing import Queue    # 进程间通信Queue,两者不要混淆

importqueue                            # 线程间通信queue.Queue,两者不要混淆

importtime

defp_put(q,*args):

    q.put(args)

    print('Has put %s'%args)

defp_get(q,*args):

    print('%s wait to get...'%args)

    print(q.get())

    print('%s got it'%args)

if__name__=="__main__":

    q=queue.Queue()

    p1=Process(target=p_put,args=(q,'p1',))

    p2=Process(target=p_get,args=(q,'p2',))

    p1.start()

    p2.start()

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

直接异常报错:

Traceback(mostrecentcalllast):

  File"E:/Project/python_project/untitled10/123.py",line38,in<module>

    p1.start()

  File"G:\ProgramData\Anaconda3\lib\multiprocessing\process.py",line105,instart

    self._popen=self._Popen(self)

  File"G:\ProgramData\Anaconda3\lib\multiprocessing\context.py",line223,in_Popen

    return_default_context.get_context().Process._Popen(process_obj)

  File"G:\ProgramData\Anaconda3\lib\multiprocessing\context.py",line322,in_Popen

    returnPopen(process_obj)

  File"G:\ProgramData\Anaconda3\lib\multiprocessing\popen_spawn_win32.py",line65,in__init__

    reduction.dump(process_obj,to_child)

  File"G:\ProgramData\Anaconda3\lib\multiprocessing\reduction.py",line60,indump

    ForkingPickler(file,protocol).dump(obj)

TypeError:can'tpickle_thread.lockobjects

1

2

3

4

5

6

7

8

9

10

11

12

13

14

另外有需要云服务器可以了解下创新互联cdcxhl.cn,海内外云服务器15元起步,三天无理由+7*72小时售后在线,公司持有idc许可证,提供“云服务器、裸金属服务器、高防服务器、香港服务器、美国服务器、虚拟主机、免备案服务器”等云主机租用服务以及企业上云的综合解决方案,具有“安全稳定、简单易用、服务可用性高、性价比高”等特点与优势,专为企业上云打造定制,能够满足用户丰富、多元化的应用场景需求。

网页标题:python进程使用Queue和Pipe通信-创新互联
文章路径:https://www.cdcxhl.com/article46/ddgjhg.html

成都网站建设公司_创新互联,为您提供网站收录品牌网站建设商城网站搜索引擎优化云服务器网站内链

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联

成都网站建设公司