主進程建立守護進程(子進程)python
那麼主進程就是被守護進程安全
注意:進程之間是相互獨立的,主進程代碼運行結束,守護進程隨即終止.併發
from multiprocessing import Process import time def task(): print('sub start') print('sub over') if __name__ == '__main__': p =Process(target=task) p.daemon = True # 將這個進程設置成子進程,必須放在p.start()前面 p.start() print('parent start') time.sleep(1) # 這裏加延時,就是爲了讓子進程運行完畢,不然,就會出現子進程(守護進程)尚未運行徹底,主程序(被守護進程)就已經運行完並結束代碼了 print('parent over') # 若是沒有在主程序這裏加延時,則不會打印子進程,由於在操做系統開啓子進程時,主程序代碼已經運行完畢. parent start sub start sub over parent over
由於子進程的內存時相互隔離的,因此進程之間數據不共享;若是多個在子進程同時訪問同一個文件,或者打印同一個終端,那麼就會帶來競爭,競爭帶來的結果就是錯亂,這個就是進程安全問題.app
這裏進程1和進程2,之因此把範圍放這麼大,是爲了能顯示出問題打印ui
from multiprocessing import Process def task1(): for i in range(10000): print('sub1 run') print('sub1 over') def task2(): for i in range(10000): print('sub2 run') print('sub2 over') if __name__ == '__main__': p1 = Process(target=task1) p2 = Process(target=task2) p1.start() p2.start() sub1 over sub2 over sub1 run sub2 run sub1 over sub2 over
什麼是互斥鎖?操作系統
互相排斥的鎖code
原理:隊列
就是將要操做公共資源的代碼鎖起來 以保證同一時間只能有一個進程在執行這部分代碼進程
進程之間數據不共享,可是共享同一套文件系統,同時訪問同一個文件,或者打印同一個終端,那麼就會產生競爭,競爭帶來的結果就是錯亂,如何控制,就是加鎖處理ip
爲了解決上面出現由於子進程競爭而出現的進程安全問題,爲了解決這個問題,咱們用到了互斥鎖.
from multiprocessing import Process,Lock def task1(mutex): mutex.acquire() for i in range(10000): print('sub1 run') print('sub1 over') mutex.release() def task2(mutex): mutex.acquire() for i in range(10000): print('sub2 run') print('sub2 over') mutex.release() if __name__ == '__main__': mutex = Lock() p1 = Process(target=task1,args=(mutex,)) p2 = Process(target=task2,args=(mutex,)) p1.start() p2.start()
def task1(): global lock if lock == False: lock = True open("aaa.txt","wt") lock = False def task2(): global lock if lock == False: lock = True open("aaa.txt","wt") lock = False
從這能夠看出,鎖並非把數據鎖住不讓用,而是讓代碼不執行.
多個子進程同時讀寫一個共享文件,雖然加了鎖,但有時也會形成文件錯亂問題,由於子進程之間數據不互通,即數據不一樣步.那麼咱們就須要建立一個同步通道
from multiprocessing import Process,Manager,Lock import time def task(data,lock): lock.acquire() num = data[0] time.sleep(0.2) data[0] = num -1 lock.release() if __name__ == '__main__': d = [100] m = Manager() # 建立一個管理器 sync_list = m.list(d) # 讓管理器建立一個進程同步的列表(也能夠是字典等) lock = Lock() # 建立一個鎖 ps = [] for i in range(10): p = Process(target=task,args=(sync_list,lock)) p.start() ps.append(p) for p in ps:p.join() print(d) print(sync_list) sub over sub over sub over sub over sub over sub over sub over sub over sub over sub over [100] [90]
總結:
加鎖能夠保證多個進程修改同一塊數據時,同一時間只能有一個任務能夠進行修改,即將併發改爲串行,保證了數據安全,可是犧牲了速度.
雖然能夠用文件共享數據實現進程間通訊,但問題是:
這種方式適合交互不頻繁,數據量大的狀況,
對於交互頻繁,數據量小的狀況不合適,所以咱們用另一種解決方案:IPC(進程間通訊)--隊列+管道
進程間相互隔離,要實現進程間通訊(IPC),multiprocess模塊支持兩種形式:隊列和管道,這兩種方式都是使用消息傳遞的
隊列是先進先出
from multiprocessing import Queue q = Queue(2) # 建立隊列,而且同時只能存儲兩個元素,若是不寫,默認爲無限大 q.put(1) # 將數據存入管道 q.put(2) # q.put(3,block=False,timeout=3) # block=True表示阻塞,默認爲True; timeout=3表示等待延時3s,默認爲None; # 當容器中沒有位置了就阻塞,等待3秒,在這個時間段有人從管道里面取走一個元素, # 那麼元素3就會存入進去,不然就會拋出錯誤 queue.Full print(q.get()) # get 是將數據取出來 而且是先進先出 print(q.get()) # print(q.get(block=True,timeout=3)) # 默認是阻塞,直到有人存入元素, 跟存入同樣.