當有兩個或跟多個線程或進程需要操作一個變量或進程時,會出現意想不到的結果,這是因爲線程或進程時迸發進行的,對同意變量或文件操作時,會出現同時對其操作,從到導致邏輯錯誤。
#!/bin/usr/env python #coding:utf-8 import multiprocessing import time class multF(multiprocessing.Process): """docstring for multF""" def __init__(self,filename,proname,stime): multiprocessing.Process.__init__(self) self.filename = filename self.proname = proname self.stime = stime def run(self): with open(self.filename,'a') as f: for x in xrange(1,5): f.write("進程編號:"+str(self.proname)+"---"+str(x)+'\n') time.sleep(self.stime) f.close() print u"文件寫入完成." def main(): filename = './test.txt' t1 = multF(filename,'01',2) t2 = multF(filename,'02',1) t3 = multF(filename,'03',2) t1.start() t2.start() t3.start() t1.join() t2.join() t3.join() print u"結束" if __name__ == '__main__': main()
爲解決以上問題我們需要引入鎖。
鎖有兩種狀態:被鎖(locked)和沒有被鎖(unlocked)。擁有acquire()和release()兩種方法,並且遵循以下的規則:
如果一個鎖的狀態是unlocked,調用acquire()方法改變它的狀態爲locked; 如果一個鎖的狀態是locked,acquire()將會阻塞,直到另一個線程或進程調用release()方法釋放它; 如果一個鎖的狀態是unlocked,調用release()會拋出RuntimeError異常; 如果一個鎖的狀態是locked,調用release()方法改變它的狀態Wieunlocked。
解決上面兩個進程或線程同時寫一個文件的問題的方法就是:我們給寫文件的類的構造器中傳入一個鎖(lock),使用這個鎖來保護文件操作,實現在給定的時間只有一個線程寫文件。
#!/bin/usr/env python #coding:utf-8 import multiprocessing import time class multF(multiprocessing.Process): """docstring for multF""" def __init__(self,filename,proname,stime,lock): multiprocessing.Process.__init__(self) self.filename = filename self.proname = proname self.stime = stime self.lock = lock def run(self): with open(self.filename,'a') as f: self.lock.acquire() for x in xrange(1,5): f.write("進程編號:"+str(self.proname)+"---"+str(x)+'\n') time.sleep(self.stime) f.close() self.lock.release() print u"文件寫入完成." def main(): filename = './test2.txt' lock = multiprocessing.Lock() t1 = multF(filename,'01',2, lock) t2 = multF(filename,'02',1,lock) t3 = multF(filename,'03',2,lock) t1.start() t2.start() t3.start() t1.join() t2.join() t3.join() print u"結束" if __name__ == '__main__': main()