多進程(一)

多進程(一)

1.進程建立的兩種方式

開啓進程的第一種方式:
    
from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running')
    time.sleep(2)
    print(f'{name} is done')

if __name__ == '__main__':  
    #windows環境,開啓進程必須在__name__ == '__main__'下
    p = Process(target = task,args = ('alex',))
    #建立一個進程對象
    p.start()
    #只是向操做系統發出一個開闢子進程的信號,而後就執行下一行了
    #操做系統收到信號後,會從內存中開闢一個子進程空間,而後再將主進程全部數據copy到子進程,而後再調用cpu去執行(開闢子進程開銷很大),因此永遠會先執行主進程的代碼
    print('主進程運行')
    
#主進程運行
#alex is running
#alex is done
    
開啓進程的第二種方式:
    
from multiprocessing import Process
import time

class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        print(f'{self.name} is running')
        time.sleep(2)
        print(f'{self.name} is done')
        
if __name__ == '__main__':
    p = MyProcess('alex')
    p.start()
    print('主進程運行')
    
#主進程運行
#alex is running
#alex is done

簡單應用:
    
from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running')
    time.sleep(1)
    print(f'{name} is done')
    
def task1(name):
    print(f'{name} is running')
    time.sleep(2)
    print(f'{name} is done')
    
if __name__ == '__main__':
    p1 = Process(target = task,args = ('alex',))
    p2 = Process(target = task,args = ('tony',))
    start_time = time.time()
    p1.start()
    p2.start()
    #兩個進程,併發或者並行的執行三個任務
    print(f'結束時間{time.time() - start_time}')
    
#結束時間0.03194904327392578
#alex is running
#tony is running 
#alex is done
#tony is done

2.獲取進程pid

區份內存中的進程:
    命令行:獲取全部進程的pid(process id): tasklist,
          查找某個進程的pid:  tasklist|findstr 進程名

    代碼級別:
            import os
            print(os.getpid())
            
獲取父進程(主進程的pid):
    import os
    print(os.getppid())

3.驗證進程之間的空間隔離

from multiprocessing import Process
import time

name = 'alex'
def task():
    global name
    name = 'tom'
    print(f'子進程:{name}')

if __name__ == '__main__':
    p = Process(target = task)
    p.start()
    time.sleep(3)
    print(f'主進程:{name}')
    
#子進程:tom
#主進程:alex

lst = [1,2]
def task():
    global lst
    lst.append(3)
    print(f'子進程:{lst}')

if __name__ == '__main__':
    p = Process(target = task)
    p.start()
    time.sleep(3)
    print(f'主進程:{lst}')

#子進程:[1, 2, 3]
#主進程:[1, 2]

4.join方法

join:讓主進程等待子進程結束以後,再執行主進程
 
from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running')
    time.sleep(2)
    print(f'{name} is done')
 
if __name__ == '__main__':
    p = Process(target = task,args = ('alex',))
    p.start()
    p.join()
    print('主進程開始')
    
#alex is running
#alex is done
#主進程開始

多個子進程使用join,join就是阻塞,主進程有join,主進程下面的代碼一概不執行,直到進程執行完畢以後,在執行.
驗證1:

from multiprocessing import Process
import time

def task(name,sec):
    print(f'{name} is running')
    time.sleep(sec)
    print(f'{name} is done')
    
if __name__ == '__main__':
    start_time = time.time()
    p1 = Process(target = task,args = ('alex',1))
    p2 = Process(target = task,args = ('tom',2))
    p3 = Process(target = task,args = ('tony,3'))
    p1.start()
    p2.start()
    p3.start()
    p1.join() #join只針對主進程,若是join下面屢次join,則不阻塞
    p2.join()
    p3.join()
    print(f'主進程:{time.time() - start_time}')
    
#alex is running
#tom is running
#tony is running
#alex is done
#tom is done
#tony is done
#主進程:3.1952016353607178

驗證2:
  
from multiprocessing import Process
import time

def task(name,sec):
    print(f'{name} is running')
    time.sleep(sec)
    print(f'{name} is done')
    
if __name__ == '__main__':
    start_time = time.time()
    p1 = Process(target = task,args = ('alex',1))
    p2 = Process(target = task,args = ('tom',2))
    p3 = Process(target = task,args = ('tony,3'))
    p1.start()
    p1.join()
    p2.start()
    p2.join()
    p3.start()
    p3.join()
    print(f'主進程:{time.time() - start_time}')

#alex is running
#alex is done
#tom is running
#tom is done
#tony is running
#tony is done
#主進程:6.42280125617981

優化上面的代碼:
 
from multiprocessing import Process
import time

def task(name,sec):
    print(f'{name} is running')
    time.sleep(sec)
    print(f'{name} is done')
    
if __name__ == '__main__':
    start_time = time.time()
    lst = []
    for i in range(1,4):
        p = Process(target = task,args = (i,))
        lst.append(p)
        p.start()     #循環時間很快,基本能夠實現同時發出指令
    for i in lst:
        i.join()
    print(f'主進程:{time.time() - start_time}')

5.進程的其餘屬性

from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running')
    time.sleep(2)
    print(f'{name} is done')
    
if __name__ == '__main__':
    p = Process(target = task,args = ('alex',)name = 'tony')
    p.start()
    p.terminate()  #殺死子進程,沒有阻塞則子程序還沒運行就被殺死
    print(P.is_alive())   #看子進程是否還活着,輸出True/False 
    print(p.name)  #輸出以前給p添加的name屬性
    print("主進程運行")

6.守護進程

守護進程:
    子進程守護主進程,只要主進程結束,子進程跟着就結束
    
from multiprocessing import Process
import time

def task(name):
    print(f'{name} is running')
    time.sleep(2)
    print(f'{name} is done')
    
if __name__ == '__main__':
    p = Process(target = task,args = ('alex',))
    p.daemon = True #將子進程p設置成守護進程,主進程結束,子進程也結束
    p.start()
    #p.daemon = True #必定要在子進程開啓以前設置,不然報錯
    time.sleep(1)
    print('主進程運行')
    
#alex is running
#主進程運行
相關文章
相關標籤/搜索