python多进程和多线程使用场景_Python36 多线程、多进程的使用场景
多線程與多進(jìn)程的使用場景
io 操作不占用CPU(從硬盤、從網(wǎng)絡(luò)、從內(nèi)存讀數(shù)據(jù)都算io)
計算占用CPU(如1+1計算)
python中的線程是假線程,不同線程之間的切換是需要耗費資源的,因為需要存儲線程的上下文,不斷的切換就會耗費資源。。
python多線程適合io操作密集型的任務(wù)(如socket server 網(wǎng)絡(luò)并發(fā)這一類的);
python多線程不適合cpu密集操作型的任務(wù),主要使用cpu來計算,如大量的數(shù)學(xué)計算。
那么如果有cpu密集型的任務(wù)怎么辦,可以通過多進(jìn)程來操作(不是多線程)。
假如CPU有8核,每核CPU都可以用1個進(jìn)程,每個進(jìn)程可以用1個線程來進(jìn)行計算。
進(jìn)程之間不需要使用gil鎖,因為進(jìn)程是獨立的,不會共享數(shù)據(jù)。
進(jìn)程可以起很多個,但是8核CPU同時只能對8個任務(wù)進(jìn)行操作。
多進(jìn)程
測試多進(jìn)程
import multiprocessing
import time
def run(name):
time.sleep(2)
print ('heelo',name)
if __name__ == '__main__':
for i in range(10): #起了10個進(jìn)程
p = multiprocessing.Process(target=run,args=('bob%s' %i,))
p.start()
執(zhí)行結(jié)果:
heelo bob1
heelo bob0
heelo bob2
heelo bob3
heelo bob5
heelo bob4
heelo bob6
heelo bob7
heelo bob8
heelo bob9
##2秒左右就執(zhí)行完成了,有幾核CPU,同時就可以處理幾個進(jìn)程;當(dāng)然要考慮你的電腦還開啟了N多個其他應(yīng)用程序,不過CPU計算比較快。
import multiprocessing
import time,threading
def thread_run():
print (threading.get_ident()) #get_ident獲取當(dāng)前線程id
def run(name):
time.sleep(2)
print ('heelo',name)
t = threading.Thread(target=thread_run,) #在每個進(jìn)程中又起了1個線程
t.start()
if __name__ == '__main__':
for i in range(10): #起了10個進(jìn)程
p = multiprocessing.Process(target=run,args=('bob%s' %i,))
p.start()
執(zhí)行結(jié)果:
heelo bob0
16684
heelo bob1
15052
heelo bob2
15260
heelo bob3
6192
heelo bob4
6748
heelo bob7
13980
heelo bob5
6628
heelo bob6
3904
heelo bob9
2328
heelo bob8
17072
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid()) #獲取父進(jìn)程的id
print('process id:', os.getpid()) #獲取自身的id
print("\n\n")
def f(name):
info('\033[31;1mfunction f\033[0m')
print('hello', name)
if __name__ == '__main__':
info('\033[32;1mmain process line\033[0m') ##直接調(diào)用函數(shù)
# p = Process(target=f, args=('bob',))
# p.start()
# p.join()
執(zhí)行結(jié)果:
main process line
module name: __main__
parent process: 1136 #父進(jìn)程ID,這個父進(jìn)程就是pycharm
process id: 16724 #這個子進(jìn)程就是python的代碼程序
##每個進(jìn)程都會有一個父進(jìn)程。
from multiprocessing import Process
import os
def info(title):
print(title)
print('module name:', __name__)
print('parent process:', os.getppid()) #獲取父進(jìn)程的id
print('process id:', os.getpid()) #獲取自身的id
print("\n\n")
def f(name):
info('\033[31;1mcalled from child process function f\033[0m')
print('hello', name)
if __name__ == '__main__':
info('\033[32;1mmain process line\033[0m')
p = Process(target=f, args=('bob',)) #設(shè)置子進(jìn)程
p.start() #啟動子進(jìn)程
# p.join()
執(zhí)行結(jié)果:
main process line
module name: __main__
parent process: 1136 #主進(jìn)程pycharm
process id: 14684 #子進(jìn)程python代碼
called from child process function f
module name: __mp_main__
parent process: 14684 #主進(jìn)程python代碼(1136的子進(jìn)程)
process id: 15884 #python代碼(主進(jìn)程14684)中的子進(jìn)程的子15884
## 每個進(jìn)程都有主進(jìn)程(父進(jìn)程)
hello bob
進(jìn)程間通訊
默認(rèn)進(jìn)程之間數(shù)據(jù)是不共享的,如果一定要實現(xiàn)互訪可以通過Queue來實現(xiàn),這個Queue和線程中的Queue使用方法一樣,不過線程中的Queue只能在線程之間使用。
線程
import queue
import threading
def f():
q.put([42,None,'heelo'])
if __name__ == '__main__':
q = queue.Queue()
p = threading.Thread(target=f,)
p.start()
print (q.get())
p.join()
執(zhí)行結(jié)果:
[42, None, 'heelo']
## 通過子線程put進(jìn)去數(shù)據(jù),然后在主線程get出內(nèi)容,表明線程之間數(shù)據(jù)是可以共享的。
進(jìn)程
import queue
from multiprocessing import Process
def f():
q.put([42,None,'heelo']) #這里的q屬于主進(jìn)程
if __name__ == '__main__':
q = queue.Queue() #主進(jìn)程起的q
p = Process(target=f,)
## 在主進(jìn)程中來定義子進(jìn)程;如果在主進(jìn)程中啟動了子進(jìn)程,那么主進(jìn)程和子進(jìn)程之間內(nèi)存是獨立的。
## 因為內(nèi)存獨立,子進(jìn)程p是無法訪問主進(jìn)程def f()中的q的。
p.start()
print (q.get())
p.join()
執(zhí)行結(jié)果:
Process Process-1:
Traceback (most recent call last):
File "D:\python3.6.4\lib\multiprocessing\process.py", line 258, in _bootstrap
self.run()
File "D:\python3.6.4\lib\multiprocessing\process.py", line 93, in run
self._target(*self._args, **self._kwargs)
File "E:\python\代碼練習(xí)\A3.py", line 7, in f
q.put([42,None,'heelo'])
NameError: name 'q' is not defined
##可以看到已經(jīng)報錯,這是因為子進(jìn)程不能訪問主進(jìn)程的q
import queue
from multiprocessing import Process
def f(qq):
qq.put([42,None,'heelo'])
if __name__ == '__main__':
q = queue.Queue()
p = Process(target=f,args=(q,)) #將父進(jìn)程q傳給子進(jìn)程
p.start()
print (q.get())
p.join()
執(zhí)行結(jié)果:
Traceback (most recent call last):
File "E:/python/代碼練習(xí)/A3.py", line 13, in
p.start()
File "D:\python3.6.4\lib\multiprocessing\process.py", line 105, in start
self._popen = self._Popen(self)
File "D:\python3.6.4\lib\multiprocessing\context.py", line 223, in _Popen
return _default_context.get_context().Process._Popen(process_obj)
File "D:\python3.6.4\lib\multiprocessing\context.py", line 322, in _Popen
return Popen(process_obj)
File "D:\python3.6.4\lib\multiprocessing\popen_spawn_win32.py", line 65, in __init__
reduction.dump(process_obj, to_child)
File "D:\python3.6.4\lib\multiprocessing\reduction.py", line 60, in dump
ForkingPickler(file, protocol).dump(obj)
TypeError: can't pickle _thread.lock objects
## 這是因為我們將線程的q傳給另一個進(jìn)程,這是不可以的,線程只屬于當(dāng)前進(jìn)程,不能傳給其他進(jìn)程。
## 如果想將q傳給子進(jìn)程,那么必須將進(jìn)程q傳進(jìn)去,而不是線程q。
from multiprocessing import Process,Queue
##大寫的Queue是進(jìn)程隊列; queue是線程隊列
##大寫的Queue需要從multiprocessing導(dǎo)入
def f(qq):
qq.put([42,None,'heelo'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f,args=(q,)) #將父進(jìn)程q傳給子進(jìn)程
p.start()
print (q.get()) #父進(jìn)程去get子進(jìn)程的內(nèi)容
p.join()
執(zhí)行結(jié)果:
[42, None, 'heelo']
##父進(jìn)程可以get子進(jìn)程put進(jìn)去的內(nèi)容了;從表面上看感覺是兩個進(jìn)程共享了數(shù)據(jù),其實不然。
## 現(xiàn)在已經(jīng)實現(xiàn)了進(jìn)程間的通訊。父進(jìn)程將q傳給子進(jìn)程,其實是克隆了一份q給子進(jìn)程,此時子進(jìn)程就多了一個q進(jìn)程隊列; 但是父進(jìn)程又為什么能夠get子進(jìn)程put進(jìn)去的數(shù)據(jù)呢,這是因為當(dāng)前兩個進(jìn)程在內(nèi)存空間依然是獨立的,只不過子進(jìn)程put的數(shù)據(jù) 通過pickle序列化放到內(nèi)存中一個中間的位置,然后父進(jìn)程從這個中間的位置取到數(shù)據(jù)(而不是從子進(jìn)程中取的數(shù)據(jù))。 所以進(jìn)程間的通訊不是共享數(shù)據(jù),而是一個數(shù)據(jù)的傳遞。
進(jìn)程之間的數(shù)據(jù)還可以通過管道的方式來通訊
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child1']) #發(fā)送數(shù)據(jù)給parent_conn
conn.close() #發(fā)完數(shù)據(jù)需要關(guān)閉
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
## 生成管道。 生成時會產(chǎn)生兩個返回對象,這兩個對象相當(dāng)于兩端的電話,通過管道線路連接。
## 兩個對象分別交給兩個變量。
p = Process(target=f, args=(child_conn,)) #child_conn需要傳給對端,用于send數(shù)據(jù)給parent_conn
p.start()
print(parent_conn.recv()) #parent_conn在這端,用于recv數(shù)據(jù)
p.join()
執(zhí)行結(jié)果:
[42, None, 'hello from child1']
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child1'])
conn.send([42, None, 'hello from child2']) #發(fā)送兩次數(shù)據(jù)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv())
p.join()
執(zhí)行結(jié)果:
[42, None, 'hello from child1']
## 可以看到這端只接收到了一次數(shù)據(jù)
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child1'])
conn.send([42, None, 'hello from child2'])
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv())
print(parent_conn.recv()) #第二次接收數(shù)據(jù)
p.join()
執(zhí)行結(jié)果:
[42, None, 'hello from child1']
[42, None, 'hello from child2']
##對端發(fā)送幾次,這端就需要接收幾次
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child1'])
conn.send([42, None, 'hello from child2']) #發(fā)送兩次數(shù)據(jù)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv())
print(parent_conn.recv())
print(parent_conn.recv()) #對端發(fā)送兩次,本段接收三次
p.join()
執(zhí)行結(jié)果:
[42, None, 'hello from child1']
[42, None, 'hello from child2']
## 程序卡主了,除非對端在發(fā)送一次數(shù)據(jù)。
from multiprocessing import Process, Pipe
def f(conn):
conn.send([42, None, 'hello from child1'])
conn.send([42, None, 'hello from child2']) #發(fā)送兩次數(shù)據(jù)
print (conn.recv()) #接收數(shù)據(jù)
conn.close()
if __name__ == '__main__':
parent_conn, child_conn = Pipe()
p = Process(target=f, args=(child_conn,))
p.start()
print(parent_conn.recv())
print(parent_conn.recv())
parent_conn.send("data from parent_conn") #發(fā)送數(shù)據(jù)
p.join()
執(zhí)行結(jié)果:
[42, None, 'hello from child1']
[42, None, 'hello from child2']
data from parent_conn
##通過管道實現(xiàn)了相互發(fā)送接收數(shù)據(jù)(實現(xiàn)了數(shù)據(jù)傳遞)
進(jìn)程間數(shù)據(jù)交互及共享
from multiprocessing import Process, Manager
import os
def f(d, l):
d[1] = '1' #放入key和value到空字典中
d['2'] = 2
d[0.25] = None
l.append(os.getpid()) #將每個進(jìn)程的id值放入列表中;每個進(jìn)程的id值都不同。
print(l)
if __name__ == '__main__':
with Manager() as manager: #做一個別名,此時manager就相當(dāng)于Manager()
d = manager.dict() #生成一個可在多個進(jìn)程之間傳遞和共享的字典
l = manager.list(range(5)) #生成一個可在多個進(jìn)程之間傳遞和共享的列表;通過range(5)給列表中生成5個數(shù)據(jù)
p_list = []
for i in range(10): #生成10個進(jìn)程
p = Process(target=f, args=(d, l)) #將字典和列表傳給每個進(jìn)程,每個進(jìn)程可以進(jìn)行修改
p.start()
p_list.append(p) # 將每個進(jìn)程放入空列表中
for res in p_list:
res.join()
print(d) #所有進(jìn)程都執(zhí)行完畢后打印字典
print(l) #所有進(jìn)程都執(zhí)行完畢后打印列表
執(zhí)行結(jié)果:
[0, 1, 2, 3, 4, 15788]
#列表生成的時候自動加入了0-4這5個數(shù)字;然后每個進(jìn)程都將各自的pid加入到列表。
[0, 1, 2, 3, 4, 15788, 1568]
[0, 1, 2, 3, 4, 15788, 1568, 7196]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952, 15704]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952, 15704, 14412]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952, 15704, 14412, 5368]
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952, 15704, 14412, 5368, 3092] #第10個進(jìn)程打印的列表中有10個進(jìn)程的pid
{1: '1', '2': 2, 0.25: None} #最后打印的字典
[0, 1, 2, 3, 4, 15788, 1568, 7196, 6544, 9568, 16952, 15704, 14412, 5368, 3092] #最后打印的列表
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() #對字典做個調(diào)整,也將pid加入到字典中
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)
執(zhí)行結(jié)果:
[0, 1, 2, 3, 4, 2240]
[0, 1, 2, 3, 4, 2240, 10152]
[0, 1, 2, 3, 4, 2240, 10152, 10408]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184, 16168]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184, 16168, 11384]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184, 16168, 11384, 15976]
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184, 16168, 11384, 15976, 16532]
{2240: 2240, 10152: 10152, 10408: 10408, 6312: 6312, 17156: 17156, 6184: 6184, 16168: 16168, 11384: 11384, 15976: 15976, 16532: 16532}
[0, 1, 2, 3, 4, 2240, 10152, 10408, 6312, 17156, 6184, 16168, 11384, 15976, 16532]
##現(xiàn)在我們看到可以實現(xiàn)進(jìn)程間的數(shù)據(jù)共享、修改和傳遞。
##Manager()自帶鎖,會控制進(jìn)程之間同一時間修改數(shù)據(jù);
##字典和列表的數(shù)據(jù)不是一份,而是因為10個進(jìn)程,所以有10個字典和10個列表。每個進(jìn)程修改后,都會copy給其他進(jìn)程,其他進(jìn)程可以對最新的數(shù)據(jù)進(jìn)行修改,所以數(shù)據(jù)不會被修改亂。
進(jìn)程同步
在進(jìn)程里面也有鎖
from multiprocessing import Process, Lock #從multiprocessing導(dǎo)入Lock這個鎖
def f(l, i):
l.acquire() #獲取修改數(shù)據(jù)的鎖
print('hello world', i)
l.release() #釋放鎖
if __name__ == '__main__':
lock = Lock() #實例鎖
for num in range(10): #生成10個進(jìn)程
Process(target=f, args=(lock, num)).start() #執(zhí)行子進(jìn)程并傳入?yún)?shù)給子進(jìn)程
執(zhí)行結(jié)果:
hello world 1
hello world 4
hello world 0
hello world 3
hello world 2
hello world 5
hello world 6
hello world 8
hello world 7
hello world 9
## 可以看到一共10個進(jìn)程,并不是連續(xù)的,說明執(zhí)行進(jìn)程的時候說不準(zhǔn)先執(zhí)行哪個進(jìn)程。
##進(jìn)程之間數(shù)據(jù)是獨立的,這里我們?yōu)槭裁从忠渔i呢,這是因為所有進(jìn)程使用同一個屏幕來輸出數(shù)據(jù);比如 我們現(xiàn)在輸出的數(shù)據(jù)是 hello world x,在輸出的過程中很有可能其中一個進(jìn)程還沒輸出完(比如只輸出了hello wo),另一個進(jìn)程就執(zhí)行輸出了(可能會在屏幕上看到hello wohello world0201的現(xiàn)象)。 所以需要通過鎖來控制同一時間只能有一個進(jìn)程輸出數(shù)據(jù)到屏幕。
進(jìn)程池
執(zhí)行多進(jìn)程,子進(jìn)程會從主進(jìn)程復(fù)制一份完整數(shù)據(jù),1個、10個進(jìn)程可能還沒什么感覺,但是如果有100或1000,甚至更多個進(jìn)程的時候開銷就會特別大,就會明顯感覺到多進(jìn)程執(zhí)行有卡頓現(xiàn)象。
進(jìn)程池可以設(shè)定同一時間有多少個進(jìn)程可以在CPU上運行。
from multiprocessing import Process, Pool
#從multiprocessing導(dǎo)入pool
import time,os
def Foo(i):
time.sleep(2)
print("in process",os.getpid()) #打印進(jìn)程id
return i + 100
def Bar(arg):
print('-->exec done:', arg)
if __name__ == '__main__': ##這行代碼用途是如果主動執(zhí)行該代碼的.py文件,則該代碼下面的代碼可以被執(zhí)行;如果該.py模塊被導(dǎo)入到其他模塊中,從其他模塊執(zhí)行該.py模塊,則該行下面的代碼不會被執(zhí)行。 有些時候可以用這種方式用于測試,在該行代碼下面寫一些測試代碼。。
pool = Pool(5) #同時只能放入5個進(jìn)程
for i in range(10): #創(chuàng)建10個進(jìn)程,但是因為pool的限制,只有放入進(jìn)程池中的5個進(jìn)程才會被執(zhí)行(),其他的被掛起了,如果進(jìn)程池中其中有兩個進(jìn)程執(zhí)行完了,就會補(bǔ)進(jìn)2個進(jìn)程進(jìn)去。
# pool.apply_async(func=Foo, args=(i,), callback=Bar)
pool.apply(func=Foo, args=(i,)) #pool.apply用來將進(jìn)程放入pool
print('end') #執(zhí)行完畢
pool.close() #允許pool中的進(jìn)程關(guān)閉(close必須在join前面,可以理解close相當(dāng)于一個開關(guān)吧)
pool.join() # 進(jìn)程池中進(jìn)程執(zhí)行完畢后再關(guān)閉,如果注釋,那么程序直接關(guān)閉。
執(zhí)行結(jié)果:
in process 2240
in process 3828
in process 16396
in process 11848
in process 11636
in process 2240
in process 3828
in process 16396
in process 11848
in process 11636
end
##可以看到通過串行的方式將結(jié)果打印出來,這是因為我們使用的是pool.apply。 pool.apply就是通過串行的方式來執(zhí)行。
from multiprocessing import Process, Pool
import time,os
def Foo(i):
time.sleep(2)
print("in process",os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg)
if __name__ == '__main__':
pool = Pool(5)
for i in range(10):
pool.apply_async(func=Foo, args=(i,))
## 使用pool.apply_async就可以并行了
print('end')
pool.close()
# pool.join() 注釋掉
執(zhí)行結(jié)果:
end
## 只執(zhí)行了print('end')代碼,其他進(jìn)程的結(jié)果沒有看到,這是因為其他進(jìn)程還沒有執(zhí)行完成,主進(jìn)程pool.close()就執(zhí)行完了,close以后所有其他進(jìn)程也不會在執(zhí)行了。
## 要想其他進(jìn)程執(zhí)行完成后在關(guān)閉,必須使用pool.join()
from multiprocessing import Process, Pool
import time,os
def Foo(i):
time.sleep(2)
print("in process",os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg)
if __name__ == '__main__':
pool = Pool(5)
for i in range(10):
pool.apply_async(func=Foo, args=(i,))
print('end')
pool.close()
pool.join()
執(zhí)行結(jié)果:
end
in process 13272
in process 14472
in process 3724
in process 9072
in process 15068
in process 13272
in process 14472
in process 3724
in process 9072
in process 15068
##從執(zhí)行結(jié)果來看,5個 5個的被打印出來。
回調(diào)
from multiprocessing import Process, Pool
import time,os
def Foo(i):
time.sleep(2)
print("in process",os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg,os.getpid())
if __name__ == '__main__':
pool = Pool(5)
print ("主進(jìn)程:",os.getpid()) #打印主進(jìn)程id
for i in range(10):
pool.apply_async(func=Foo, args=(i,),callback=Bar)
##callback叫做回調(diào),就是當(dāng)執(zhí)行完了func=Foo后,才會執(zhí)行callback=Bar(每個進(jìn)程執(zhí)行完了后都會執(zhí)行回調(diào))。
## 回調(diào)可以用于當(dāng)執(zhí)行完代碼后做一些后續(xù)操作,比如查看完命令后,通過回調(diào)進(jìn)行備份;或者執(zhí)行完什么動作后,做個日志等。
## 備份、寫日志等在子進(jìn)程中也可以執(zhí)行,但是為什么要用回調(diào)呢! 這是因為如果用子進(jìn)程,有10個子進(jìn)程就得連接數(shù)據(jù)庫十次,而使用回調(diào)的話是用主進(jìn)程連接數(shù)據(jù)庫,所以只連接一次就可以了,這樣寫能大大提高運行效率。
##通過主進(jìn)程建立數(shù)據(jù)庫的連接的話,因為在同一個進(jìn)程中只能在數(shù)據(jù)庫建立一次連接,所以即使是多次被子進(jìn)程回調(diào),也不會重復(fù)建立連接的,因為數(shù)據(jù)庫會限制同一個進(jìn)程最大連接數(shù),這都是有數(shù)據(jù)庫設(shè)置的。
print('end')
pool.close()
pool.join()
執(zhí)行結(jié)果:
主進(jìn)程: 12776 #主進(jìn)程是12766
end
in process 7496
-->exec done: 100 12776 #這里可以看出回調(diào)是通過主進(jìn)程調(diào)用的
in process 3324
-->exec done: 101 12776
in process 16812
-->exec done: 102 12776
in process 10876
-->exec done: 103 12776
in process 8200
-->exec done: 104 12776
in process 7496
-->exec done: 105 12776
in process 3324
-->exec done: 106 12776
in process 16812
-->exec done: 107 12776
in process 10876
-->exec done: 108 12776
in process 8200
-->exec done: 109 12776
總結(jié)
以上是生活随笔為你收集整理的python多进程和多线程使用场景_Python36 多线程、多进程的使用场景的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: sap fiori导出列表到excel_
- 下一篇: 广州python平均薪资_爬取广州的py