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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM