随笔 - 331,  文章 - 92,  评论 - 54,  阅读 - 60万

#先来看下如何实现多进程

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
# multiprocessing 这个是python的多进程的模块,我们会用到这个模块的很多方法
from multiprocessing import Process
import threading
import time
 
def f(name):
    time.sleep(2)
    print("hello,",name)
 
if __name__ == '__main__':
    p1 = Process(target=f,args=("bob",))
    p2 = Process(target=f, args=("aob",))
    #多进程
 
    # p1 = threading.Thread(target=f,args=("bob",))
    # p2 = threading.Thread(target=f,args=("add",))
    # 多线程
    p1.start()
    p2.start()
    p1.join() 

 

进程和进程之间是不能共享数据的,比如我们看下面的例子

1
2
3
4
5
6
7
8
9
import multiprocessing
from multiprocessing import Queue
def test_func():
    test_queue.put("aa")
 
if __name__ == '__main__':
    test_queue = Queue()
    test_func()
    print(test_queue.get())

  

结果如下

1
 

  

我们在看一个例子,通过子进程去运行函数test_func()

1
2
3
4
5
6
7
8
9
10
11
import multiprocessing
from multiprocessing import Queue
def test_func():
    test_queue.put("aa")
 
if __name__ == '__main__':
    test_queue = Queue()
    p = multiprocessing.Process(target=test_func)
    p.start()
    # test_func()
    # print(test_queue.get())

  

下面我们来讲解下

第一个例子,我们从头到尾只有一个进程在执行,所以在函数test_func中,可以直接使用外面定义的变量队列

第二个例子,我们通过子进程去启动函数test_func,由于子进程和自己的父进程不是同一个进程,所以,在test_func中不能直接使用变量队列,运行脚本会直接报错的,此时我们如想在子线程中使用变量队列,就只能通过函数传参的方式将队列传递进去,就比如下面的例子

1
2
3
4
5
6
7
8
9
10
11
import multiprocessing
from multiprocessing import Queue
def test_func(test_queue):
    test_queue.put("aa")
 
 
if __name__ == '__main__':
    test_queue = Queue()
    p = multiprocessing.Process(target=test_func,args=(test_queue,))
    p.start()
    print(test_queue.get())

  

 

 

#在看来子进程和父进程

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
from multiprocessing import Process
import os
 
def info(title):
    print(title)
    print("module name,",__name__)
    print("parent process,",os.getppid())
    print("process id,",os.getpid())
    print("\n\n")
 
def f(name):
    info("function f")
    print("hello,",name)
 
if __name__ == '__main__':
    info("main process line")
    #在主线程中调用info这个函数,所有这里执行的infor的函数的父进程是pycharm,而子进程id就是执行这个脚本的进程本身的id
 
    p = Process(target=info,args=("bob",))
    #这里是在多线程中调用info这个函数,调用info这个函数,那么在这里执行info这个函数,打印的父进程就是脚本本身这个进程id,而
    #这里的info函数的id就是一个新的进程id
 
    p.start()
    p.join()
 
'''
程序的执行结果如下
main process line
module name, __main__
parent process, 3132
process id, 9180
 
bob
module name, __mp_main__
parent process, 9180
process id, 5204
 
'''

 

 

#然后来看下通过Queue来实现进程之间数据交互

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
#不同进程之间的内存数据是不共享的,可以用下面的方法实现进程间的内存共享,要通过一个第三方才能通信,这里我们介绍第一个方法:用队列Queue来实现
#Queue有2个方法,一个put,一个是get,队列一定是先进先出
from multiprocessing import Process
from multiprocessing import Queue
 
def f(q):
    q.put({"k1": "v1"})
    q.put(["1","2","3"])
    q.put(["2", "2", "2"])
 
    print(q.qsize())
    #获取队列queue的大小
 
if __name__ == '__main__':
    que = Queue()
    que.qsize()
    p = Process(target=f,args=(que,))
    #这里执行这个函数,就是在执行这个脚本的进程id的子进程id
    p.start()
    print("from parent,",que.get())
    print("from parent,", que.get())
    #这里的进程id就是执行这个脚本的进程id<br>    #这里要注意,que.get如果拿不到数据,则会一直阻塞<br>
    p.join()
 
# 结果如下
'''
2
from parent, {'k1': 'v1'}
from parent, ['1', '2', '3
 
'''

 

 

#通过pipe来实现进程之间交互

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
#前面我们学习了进程之间交互数据的方法Queue,今天我们在来学习一下管道来实现进程之间的内存交互
# pipe管道,也是进程间通讯的一种方式,会返回一对对象,2个对象分别是管道的两头,一个管道是有2头,一头赋值给子进程,一头赋值给你父进程
from multiprocessing import Process
#导入多进程这个方法
 
from multiprocessing import Pipe
#导入管道这个方法
 
 
def f(conn):
    conn.send(["a","b","c"])
    conn.send(["1", "2", "3"])
    conn.close()
#在子进程里send一个数据,然后关闭管道
 
 
 
 
if __name__ == '__main__':
    parent_conn,child_conn = Pipe()
    #生成一个管道,一端是父进程,一端是子进程
    p = Process(target=f,args=(child_conn,))
    #用子进程启动函数f,f这个函数就往管道里send数据
    p.start()
    #启动上面定义的子进程
    print(parent_conn.recv())
    #通过父进程去管道中获取数据,并打印
    print(parent_conn.recv())
    # parent_conn.recv()
    # 这个recv这个方法也是阻塞的,如果没有recv到数据,则该管道会一直阻塞
    p.join()
    #等待这子进程执行完毕在退出

  

判断pipe的缓冲区是否还有数据poll(timeout=xxx)方法

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
import multiprocessing
 
def test(conn):
 
    conn.send("123")
    conn.send("456")
    conn.close()
    print(conn.writable)
 
 
if __name__ == '__main__':
    p_conn,c_conn = multiprocessing.Pipe()
 
    p = multiprocessing.Process(target=test,args=[c_conn,])
    p.start()
 
    # print(dir(p_conn))
    print(p_conn.recv())
    print(p_conn.recv())
    if not p_conn.poll(timeout=2):
        print("kong.....")
    p.join()
posted on   bainianminguo  阅读(2108)  评论(0编辑  收藏  举报
编辑推荐:
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
阅读排行:
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 无需6万激活码!GitHub神秘组织3小时极速复刻Manus,手把手教你使用OpenManus搭建本

< 2025年3月 >
23 24 25 26 27 28 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 1 2 3 4 5
点击右上角即可分享
微信分享提示