Ⅰ python中多進程+協程的使用以及為什麼要用它
前面講了為什麼python里推薦用多進程而不是多線程,但是多進程也有其自己的限制:相比線程更加笨重、切換耗時更長,並且在python的多進程下,進程數量不推薦超過CPU核心數(一個進程只有一個GIL,所以一個進程只能跑滿一個CPU),因為一個進程佔用一個CPU時能充分利用機器的性能,但是進程多了就會出現頻繁的進程切換,反而得不償失。
不過特殊情況(特指IO密集型任務)下,多線程是比多進程好用的。
舉個例子:給你200W條url,需要你把每個url對應的頁面抓取保存起來,這種時候,單單使用多進程,效果肯定是很差的。為什麼呢?
例如每次請求的等待時間是2秒,那麼如下(忽略cpu計算時間):
1、單進程+單線程:需要2秒*200W=400W秒==1111.11個小時==46.3天,這個速度明顯是不能接受的
2、單進程+多線程:例如我們在這個進程中開了10個多線程,比1中能夠提升10倍速度,也就是大約4.63天能夠完成200W條抓取,請注意,這里的實際執行是:線程1遇見了阻塞,CPU切換到線程2去執行,遇見阻塞又切換到線程3等等,10個線程都阻塞後,這個進程就阻塞了,而直到某個線程阻塞完成後,這個進程才能繼續執行,所以速度上提升大約能到10倍(這里忽略了線程切換帶來的開銷,實際上的提升應該是不能達到10倍的),但是需要考慮的是線程的切換也是有開銷的,所以不能無限的啟動多線程(開200W個線程肯定是不靠譜的)
3、多進程+多線程:這里就厲害了,一般來說也有很多人用這個方法,多進程下,每個進程都能佔一個cpu,而多線程從一定程度上繞過了阻塞的等待,所以比單進程下的多線程又更好使了,例如我們開10個進程,每個進程里開20W個線程,執行的速度理論上是比單進程開200W個線程快10倍以上的(為什麼是10倍以上而不是10倍,主要是cpu切換200W個線程的消耗肯定比切換20W個進程大得多,考慮到這部分開銷,所以是10倍以上)。
還有更好的方法嗎?答案是肯定的,它就是:
4、協程,使用它之前我們先講講what/why/how(它是什麼/為什麼用它/怎麼使用它)
what:
協程是一種用戶級的輕量級線程。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。因此:
協程能保留上一次調用時的狀態(即所有局部狀態的一個特定組合),每次過程重入時,就相當於進入上一次調用的狀態,換種說法:進入上一次離開時所處邏輯流的位置。
在並發編程中,協程與線程類似,每個協程表示一個執行單元,有自己的本地數據,與其它協程共享全局數據和其它資源。
why:
目前主流語言基本上都選擇了多線程作為並發設施,與線程相關的概念是搶占式多任務(Preemptive multitasking),而與協程相關的是協作式多任務。
不管是進程還是線程,每次阻塞、切換都需要陷入系統調用(system call),先讓CPU跑操作系統的調度程序,然後再由調度程序決定該跑哪一個進程(線程)。
而且由於搶占式調度執行順序無法確定的特點,使用線程時需要非常小心地處理同步問題,而協程完全不存在這個問題(事件驅動和非同步程序也有同樣的優點)。
因為協程是用戶自己來編寫調度邏輯的,對CPU來說,協程其實是單線程,所以CPU不用去考慮怎麼調度、切換上下文,這就省去了CPU的切換開銷,所以協程在一定程度上又好於多線程。
how:
python裡面怎麼使用協程?答案是使用gevent,使用方法:看這里
使用協程,可以不受線程開銷的限制,我嘗試過一次把20W條url放在單進程的協程里執行,完全沒問題。
所以最推薦的方法,是多進程+協程(可以看作是每個進程里都是單線程,而這個單線程是協程化的)
多進程+協程下,避開了CPU切換的開銷,又能把多個CPU充分利用起來,這種方式對於數據量較大的爬蟲還有文件讀寫之類的效率提升是巨大的。
小例子:
[python]view plain
#-*-coding=utf-8-*-
importrequests
importgevent
fromgeventimportmonkey;monkey.patch_all()
importsys
reload(sys)
sys.setdefaultencoding('utf8')
deffetch(url):
try:
s=requests.Session()
r=s.get(url,timeout=1)#在這里抓取頁面
exceptException,e:
printe
return''
defprocess_start(url_list):
tasks=[]
forurlinurl_list:
tasks.append(gevent.spawn(fetch,url))
gevent.joinall(tasks)#使用協程來執行
deftask_start(filepath,flag=100000):#每10W條url啟動一個進程
withopen(filepath,'r')asreader:#從給定的文件中讀取url
url=reader.readline().strip()
url_list=[]#這個list用於存放協程任務
i=0#計數器,記錄添加了多少個url到協程隊列
whileurl!='':
i+=1
url_list.append(url)#每次讀取出url,將url添加到隊列
ifi==flag:#一定數量的url就啟動一個進程並執行
p=Process(target=process_start,args=(url_list,))
p.start()
url_list=[]#重置url隊列
i=0#重置計數器
url=reader.readline().strip()
ifurl_listnot[]:#若退出循環後任務隊列里還有url剩餘
p=Process(target=process_start,args=(url_list,))#把剩餘的url全都放到最後這個進程來執行
p.start()
if__name__=='__main__':
task_start('./testData.txt')#讀取指定文件
細心的同學會發現:上面的例子中隱藏了一個問題:進程的數量會隨著url數量的增加而不斷增加,我們在這里不使用進程池multiprocessing.Pool來控制進程數量的原因是multiprocessing.Pool和gevent有沖突不能同時使用,但是有興趣的同學可以研究一下gevent.pool這個協程池。
Ⅱ Python多進程運行——Multiprocessing基礎教程2
上篇文章簡單介紹了multiprocessing模塊,本文將要介紹進程之間的數據共享和信息傳遞的概念。
在多進程處理中,所有新創建的進程都會有這兩個特點:獨立運行,有自己的內存空間。
我們來舉個例子展示一下:
這個程序的輸出結果是:
在上面的程序中我們嘗試在兩個地方列印全局列表result的內容:
我們再用一張圖來幫助理解記憶不同進程間的數據關系:
如果程序需要在不同的進程之間共享一些數據的話,該怎麼做呢?不用擔心,multiprocessing模塊提供了Array對象和Value對象,用來在進程之間共享數據。
所謂Array對象和Value對象分別是指從共享內存中分配的ctypes數組和對象。我們直接來看一個例子,展示如何用Array對象和Value對象在進程之間共享數據:
程序輸出的結果如下:
成功了!主程序和p1進程輸出了同樣的結果,說明程序中確實完成了不同進程間的數據共享。那麼我們來詳細看一下上面的程序做了什麼:
在主程序中我們首先創建了一個Array對象:
向這個對象輸入的第一個參數是數據類型:i表示整數,d代表浮點數。第二個參數是數組的大小,在這個例子中我們創建了包含4個元素的數組。
類似的,我們創建了一個Value對象:
我們只對Value對象輸入了一個參數,那就是數據類型,與上述的方法一致。當然,我們還可以對其指定一個初始值(比如10),就像這樣:
隨後,我們在創建進程對象時,將剛創建好的兩個對象:result和square_sum作為參數輸入給進程:
在函數中result元素通過索引進行數組賦值,square_sum通過 value 屬性進行賦值。
注意:為了完整列印result數組的結果,需要使用 result[:] 進行列印,而square_sum也需要使用 value 屬性進行列印:
每當python程序啟動時,同時也會啟動一個伺服器進程。隨後,只要我們需要生成一個新進程,父進程就會連接到伺服器並請求它派生一個新進程。這個伺服器進程可以保存Python對象,並允許其他進程使用代理來操作它們。
multiprocessing模塊提供了能夠控制伺服器進程的Manager類。所以,Manager類也提供了一種創建可以在不同流程之間共享的數據的方法。
伺服器進程管理器比使用共享內存對象更靈活,因為它們可以支持任意對象類型,如列表、字典、隊列、值、數組等。此外,單個管理器可以由網路上不同計算機上的進程共享。
但是,伺服器進程管理器的速度比使用共享內存要慢。
讓我們來看一個例子:
這個程序的輸出結果是:
我們來理解一下這個程序做了什麼:首先我們創建了一個manager對象
在with語句下的所有行,都是在manager對象的范圍內的。接下來我們使用這個manager對象創建了列表(類似的,我們還可以用 manager.dict() 創建字典)。
最後我們創建了進程p1(用於在records列表中插入一條新的record)和p2(將records列印出來),並將records作為參數進行傳遞。
伺服器進程的概念再次用下圖總結一下:
為了能使多個流程能夠正常工作,常常需要在它們之間進行一些通信,以便能夠劃分工作並匯總最後的結果。multiprocessing模塊支持進程之間的兩種通信通道:Queue和Pipe。
使用隊列來回處理多進程之間的通信是一種比較簡單的方法。任何Python對象都可以使用隊列進行傳遞。我們來看一個例子:
上面這個程序的輸出結果是:
我們來看一下上面這個程序到底做了什麼。首先我們創建了一個Queue對象:
然後,將這個空的Queue對象輸入square_list函數。該函數會將列表中的數平方,再使用 put() 方法放入隊列中:
隨後使用 get() 方法,將q列印出來,直至q重新稱為一個空的Queue對象:
我們還是用一張圖來幫助理解記憶:
一個Pipe對象只能有兩個端點。因此,當進程只需要雙向通信時,它會比Queue對象更好用。
multiprocessing模塊提供了 Pipe() 函數,該函數返回由管道連接的一對連接對象。 Pipe() 返回的兩個連接對象分別表示管道的兩端。每個連接對象都有 send() 和 recv() 方法。
我們來看一個例子:
上面這個程序的輸出結果是:
我們還是來看一下這個程序到底做了什麼。首先創建了一個Pipe對象:
與上文說的一樣,該對象返回了一對管道兩端的兩個連接對象。然後使用 send() 方法和 recv() 方法進行信息的傳遞。就這么簡單。在上面的程序中,我們從一端向另一端發送一串消息。在另一端,我們收到消息,並在收到END消息時退出。
要注意的是,如果兩個進程(或線程)同時嘗試從管道的同一端讀取或寫入管道中的數據,則管道中的數據可能會損壞。不過不同的進程同時使用管道的兩端是沒有問題的。還要注意,Queue對象在進程之間進行了適當的同步,但代價是增加了計算復雜度。因此,Queue對象對於線程和進程是相對安全的。
最後我們還是用一張圖來示意:
Python的multiprocessing模塊還剩最後一篇文章:多進程的同步與池化
敬請期待啦!
Ⅲ python 多進程讀取同一個循環處理、可以用multiprocessing
可以每個在func中加上一個參數data,data是這個線程處理的數據;
多線程處理的時候,給每個線程分配相應的data就可以了。
給個示例:
#-*-coding:utf-8-*-
importthread,threading
importtime
defFuncTest(tdata):
printtdata
classmythread(threading.Thread):
def__init__(self,threadname):
threading.Thread.__init__(self)
defrun(self):
lock.acquire()
FuncTest(ft)
lock.release()
defMutiThread(num):
threads=[]
i=0
globalft
forxinxrange(num):
threads.append(mythread(num))
fortinthreads:
time.sleep(0.5)
lock.acquire()
ft=GetThreadParam(datafile,num,i)
#print'[%s]Thread:%s,Testdata:%s'%(time.ctime(),t,ft)
i=i+1
t.start()
lock.release()
fortinthreads:
t.join()
defGetThreadParam(datafile,num,curthread):
#線程數需要小於文件行數
f=open(datafile,'r')
lines=f.readlines()
divres=divmod(len(lines),num)
ifcurthread<(num-1):
res=lines[curthread*divres[0]:(curthread+1)*divres[0]]
elifcurthread==(num-1):
res=lines[curthread*divres[0]:((curthread+1)*divres[0]+divres[1])]
returnres
f.close()
if__name__=='__main__':
globalnum,lock
datafile='a.txt'
num=3#num並發數
lock=threading.Lock()
MutiThread(num)
a.txt文件內容如下
1
2
3
4
5
6
7
8
9
10
3個線程並發時,運行結果:
>>>
['1 ', '2 ', '3 ']
['4 ', '5 ', '6 ']
['7 ', '8 ', '9 ', '10']
Ⅳ python讀取大文件處理時使用多線程
如果有個很大的文件,幾十G?,需要每次讀取一部分,處理後再讀取剩餘部分。
with open as f 已經從內部處理難點,使用 for line in f 以迭代器的形式每次讀取一行,不會有內存問題。
下面程序的思路是用一個列表存放讀取到的數據,達到長度後就開始處理,處理完就清空列表,繼續執行
Ⅳ 關於windows下使用python 多進程拷貝文件時出現拷貝空文件夾的問題
代碼有點多,沒看完。但有兩點疑問:
復制文件:為何不用shutil.,而要自己讀寫文件?
為何要多線程,有沒有先用單線程調試
Ⅵ python 多進程
基於官方文檔:
https://docs.python.org/zh-cn/3/library/multiprocessing.html
日樂購,剛才看到的一個博客,寫的都不太對,還是基於官方的比較穩妥
我就是喜歡抄官方的,哈哈
通常我們使用Process實例化一個進程,並調用 他的 start() 方法啟動它。
這種方法和 Thread 是一樣的。
上圖中,我寫了 p.join() 所以主進程是 等待 子進程執行完後,才執行 print("運行結束")
否則就是反過來了(這個不一定,看你的語句了,順序其實是隨機的)例如:
主進加個 sleep
所以不加join() ,其實子進程和主進程是各干各的,誰也不等誰。都執行完後,文件運行就結束了
上面我們用了 os.getpid() 和 os.getppid() 獲取 當前進程,和父進程的id
下面就講一下,這兩個函數的用法:
os.getpid()
返回當前進程的id
os.getppid()
返回父進程的id。 父進程退出後,unix 返回初始化進程(1)中的一個
windows返回相同的id (可能被其他進程使用了)
這也就解釋了,為啥我上面 的程序運行多次, 第一次列印的parentid 都是 14212 了。
而子進程的父級 process id 是調用他的那個進程的 id : 1940
視頻筆記:
多進程:使用大致方法:
參考: 進程通信(pipe和queue)
pool.map (函數可以有return 也可以共享內存或queue) 結果直接是個列表
poll.apply_async() (同map,只不過是一個進程,返回結果用 xx.get() 獲得)
報錯:
參考 : https://blog.csdn.net/xiemanR/article/details/71700531
把 pool = Pool() 放到 if name == " main ": 下面初始化搞定。
結果:
這個肯定有解釋的
測試多進程計算效果:
進程池運行:
結果:
普通計算:
我們同樣傳入 1 2 10 三個參數測試:
其實對比下來開始快了一半的;
我們把循環里的數字去掉一個 0;
單進程:
多進程:
兩次測試 單進程/進程池 分別為 0.669 和 0.772 幾乎成正比的。
問題 二:
視圖:
post 視圖裡面
Music 類:
直接報錯:
寫在 類裡面也 在函數里用 self.pool 調用也不行,也是相同的錯誤。
最後 把 pool = Pool 直接寫在 search 函數裡面,奇跡出現了:
前台也能顯示搜索的音樂結果了
總結一點,進程這個東西,最好 寫在 直接運行的函數裡面,而不是 一個函數跳來跳去。因為最後可能 是在子進程的子進程運行的,這是不許的,會報錯。
還有一點,多進程運行的函數對象,不能是 lambda 函數。也許lambda 虛擬,在內存??
使用 pool.map 子進程 函數報錯,導致整個 pool 掛了:
參考: https://blog.csdn.net/hedongho/article/details/79139606
主要你要,對函數內部捕獲錯誤,而不能讓異常拋出就可以了。
關於map 傳多個函數參數
我一開始,就是正常思維,多個參數,搞個元祖,讓參數一一對應不就行了:
報錯:
參考:
https://blog.csdn.net/qq_15969343/article/details/84672527
普通的 process 當讓可以穿多個參數,map 卻不知道咋傳的。
apply_async 和map 一樣,不知道咋傳的。
最簡單的方法:
使用 starmap 而不是 map
結果:
子進程結束
1.8399453163146973
成功拿到結果了
關於map 和 starmap 不同的地方看源碼:
關於apply_async() ,我沒找到多參數的方法,大不了用 一個迭代的 starmap 實現。哈哈
關於 上面源碼裡面有 itertools.starmap
itertools 用法參考:
https://docs.python.org/zh-cn/3/library/itertools.html#itertool-functions
有個問題,多進程最好不要使用全部的 cpu , 因為這樣可能影響其他任務,所以 在進程池 添加 process 參數 指定,cpu 個數:
上面就是預留了 一個cpu 干其他事的
後面直接使用 Queue 遇到這個問題:
解決:
Manager().Queue() 代替 Queue()
因為 queue.get() 是堵塞型的,所以可以提前判斷是不是 空的,以免堵塞進程。比如下面這樣:
使用 queue.empty() 空為True
Ⅶ python中多進程+協程的使用以及為什麼要用它
python是一款應用非常廣泛的腳本程序語言,谷歌公司的網頁就是用拆埋python編寫。python在生物信息、統計、網頁製作、計算等多個領域都體現出了強大的功能。python和其他腳本語言如java、R、Perl 一樣,都可以直接在命令行里運行腳本程序。工具/原料
python;CMD命令行;windows操作系統
方法/步驟
1、首先下載安裝python,建議安裝2.7版本以上,3.0版本以下,由於3.0版本以上不向下兼容,體驗較差。
2、打開文本編輯器,推薦editplus,notepad等,將文件保存成 .py格式,editplus和notepad支持識別python語法。
腳本第一行一定要寫上 #!usr/bin/python
表示該腳本文件是可執行python腳本
如果python目錄不在usr/bin目錄下,則替換成當前python執行程序的目錄。
3、編寫完腳本之後注意調試、可以直接用editplus調試。調試方法可自行網路。腳本寫完之後,打開CMD命令行,前提是python 已經被攜擾加入到環境變數中,如果沒有加入到環境變數,請百旅隱螞度
4、在CMD命令行中,輸入 「python」 + 「空格」,即 」python 「;將已經寫好的腳本文件拖拽到當前游標位置,然後敲回車運行即可。
Ⅷ python可以多進程嗎
想要充分利用多核CPU資源,Python中大部分情況下都需要使用多進程,Python中提供了multiprocessing這個包實現多進程。multiprocessing支持子進程、進程間的同步與通信,提供了Process、Queue、Pipe、Lock等組件。
開辟子進程
multiprocessing中提供了Process類來生成進程實例
Process([group [, target [, name [, args [, kwargs]]]]])
group分組,實際上不使用
target表示調用對象,你可以傳入方法的名字
args表示給調用對象以元組的形式提供參數,比如target是函數a,他有兩個參數m,n,那麼該參數為args=(m, n)即可
kwargs表示調用對象的字典
name是別名,相當於給這個進程取一個名字
先來個小例子:
# -*- coding:utf-8 -*-
from multiprocessing import Process, Pool
import os
import time
def run_proc(wTime):
n = 0
while n < 3:
print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime()) #獲取當前進程號和正在運行是的時間
time.sleep(wTime) #等待(休眠)
n += 1
if __name__ == "__main__":
p = Process(target=run_proc, args=(2,)) #申請子進程
p.start() #運行進程
print "Parent process run. subProcess is ", p.pid
print "Parent process end,{0}".format(time.ctime())
運行結果:
Parent process run. subProcess is 30196
Parent process end,Mon Mar 27 11:20:21 2017
subProcess 30196 run, Mon Mar 27 11:20:21 2017
subProcess 30196 run, Mon Mar 27 11:20:23 2017
subProcess 30196 run, Mon Mar 27 11:20:25 2017
根據運行結果可知,父進程運行結束後子進程仍然還在運行,這可能造成僵屍( zombie)進程。
通常情況下,當子進程終結時,它會通知父進程,清空自己所佔據的內存,並在內核里留下自己的退出信息。父進程在得知子進程終結時,會從內核中取出子進程的退出信息。但是,如果父進程早於子進程終結,這可能造成子進程的退出信息滯留在內核中,子進程成為僵屍(zombie)進程。當大量僵屍進程積累時,內存空間會被擠占。
有什麼辦法可以避免僵屍進程呢?
這里介紹進程的一個屬性 deamon,當其值為TRUE時,其父進程結束,該進程也直接終止運行(即使還沒運行完)。
所以給上面的程序加上p.deamon = true,看看效果。
# -*- coding:utf-8 -*-
from multiprocessing import Process, Pool
import os
import time
def run_proc(wTime):
n = 0
while n < 3:
print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())
time.sleep(wTime)
n += 1
if __name__ == "__main__":
p = Process(target=run_proc, args=(2,))
p.daemon = True #加入daemon
p.start()
print "Parent process run. subProcess is ", p.pid
print "Parent process end,{0}".format(time.ctime())
執行結果:
Parent process run. subProcess is 31856
Parent process end,Mon Mar 27 11:40:10 2017
這是問題又來了,子進程並沒有執行完,這不是所期望的結果。有沒辦法將子進程執行完後才讓父進程結束呢?
這里引入p.join()方法,它使子進程執行結束後,父進程才執行之後的代碼
# -*- coding:utf-8 -*-
from multiprocessing import Process, Pool
import os
import time
def run_proc(wTime):
n = 0
while n < 3:
print "subProcess %s run," % os.getpid(), "{0}".format(time.ctime())
time.sleep(wTime)
n += 1
if __name__ == "__main__":
p = Process(target=run_proc, args=(2,))
p.daemon = True
p.start()
p.join() #加入join方法
print "Parent process run. subProcess is ", p.pid
print "Parent process end,{0}".format(time.ctime())
執行結果:
subProcess 32076 run, Mon Mar 27 11:46:07 2017
subProcess 32076 run, Mon Mar 27 11:46:09 2017
subProcess 32076 run, Mon Mar 27 11:46:11 2017
Parent process run. subProcess is 32076
Parent process end,Mon Mar 27 11:46:13 2017
這樣所有的進程就能順利的執行了。
Ⅸ 如何使用Python實現多進程編程
1.Process
創建進程的類:Process([group[,target[,name[,args[,kwargs]]]]]),target表示調用對象,args表示調用對象的位置參數元組。kwargs表示調用對象的字典。name為別名。group實質上不使用。
方法:is_alive()、join([timeout])、run()、start()、terminate()。其中,Process以start()啟動某個進程。
屬性:authkey、daemon(要通過start()設置)、exitcode(進程在運行時為None、如果為–N,表示被信號N結束)、name、pid。其中daemon是父進程終止後自動終止,且自己不能產生新進程,必須在start()之前設置。
例1.1:創建函數並將其作為單個進程
importmultiprocessing
importtime
defworker(interval):
n=5
whilen>0:
print("Thetimeis{0}".format(time.ctime()))
time.sleep(interval)
n-=1
if__name__=="__main__":
p=multiprocessing.Process(target=worker,args=(3,))
p.start()
print"p.pid:",p.pid
print"p.name:",p.name
print"p.is_alive:",p.is_alive()
結果
12345678p.pid:8736p.name:Process-1p.is_alive:TrueThetimeisTueApr2120:55:122015ThetimeisTueApr2120:55:152015ThetimeisTueApr2120:55:182015ThetimeisTueApr2120:55:212015ThetimeisTueApr2120:55:242015
例1.2:創建函數並將其作為多個進程
importmultiprocessing
importtime
defworker_1(interval):
print"worker_1"
time.sleep(interval)
print"endworker_1"
defworker_2(interval):
print"worker_2"
time.sleep(interval)
print"endworker_2"
defworker_3(interval):
print"worker_3"
time.sleep(interval)
print"endworker_3"
if__name__=="__main__":
p1=multiprocessing.Process(target=worker_1,args=(2,))
p2=multiprocessing.Process(target=worker_2,args=(3,))
p3=multiprocessing.Process(target=worker_3,args=(4,))
p1.start()
p2.start()
p3.start()
print("ThenumberofCPUis:"+str(multiprocessing.cpu_count()))
forpinmultiprocessing.active_children():
print("childp.name:"+p.name+" p.id"+str(p.pid))
print"END!!!!!!!!!!!!!!!!!"
結果
1234567891011ThenumberofCPUis:4childp.name:Process-3p.id7992childp.name:Process-2p.id4204childp.name:Process-1p.id6380END!!!!!!!!!!!!!!!!!worker_1worker_3worker_2endworker_1endworker_2endworker_3
例1.3:將進程定義為類
importmultiprocessing
importtime
classClockProcess(multiprocessing.Process):
def__init__(self,interval):
multiprocessing.Process.__init__(self)
self.interval=interval
defrun(self):
n=5
whilen>0:
print("thetimeis{0}".format(time.ctime()))
time.sleep(self.interval)
n-=1
if__name__=='__main__':
p=ClockProcess(3)
p.start()
註:進程p調用start()時,自動調用run()
結果
12345thetimeisTueApr2120:31:302015thetimeisTueApr2120:31:332015thetimeisTueApr2120:31:362015thetimeisTueApr2120:31:392015thetimeisTueApr2120:31:422015
Ⅹ python 多進程寫入同一個文件,經常報錯:找不到文件,該怎麼處理呢有沒有大神能貼個例子之類的參考下
importthreading,time
defwrite(file,lock):
lock.acquire()#鎖住
print("開始寫出")
file.write("寫出")
print("寫出完畢")
lock.release()#解鎖
returnTrue
lock=threading.Lock()#獲取一個鎖
file=open("1.txt")
foriinrange(100):
threading.Thread(target=write,args=(file,lock)).run()