python的进程间的数据交互详解编程语言

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

# 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() 

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

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()) 

  

结果如下

aa 

  

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

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中不能直接使用变量队列,运行脚本会直接报错的,此时我们如想在子线程中使用变量队列,就只能通过函数传参的方式将队列传递进去,就比如下面的例子

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()) 

  

#在看来子进程和父进程

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来实现进程之间数据交互

#不同进程之间的内存数据是不共享的,可以用下面的方法实现进程间的内存共享,要通过一个第三方才能通信,这里我们介绍第一个方法:用队列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
#这里要注意,que.get如果拿不到数据,则会一直阻塞
p.join() # 结果如下 ''' 2 from parent, {'k1': 'v1'} from parent, ['1', '2', '3 '''

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

#前面我们学习了进程之间交互数据的方法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)方法

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() 

原创文章,作者:Maggie-Hunter,如若转载,请注明出处:https://blog.ytso.com/20877.html

(0)
上一篇 2021年7月19日
下一篇 2021年7月19日

相关推荐

发表回复

登录后才能评论