1. 程式人生 > >python進程學習

python進程學習

疑惑 start 開啟 一個隊列 14. 條件 closed style blog

學習知識點:

  1.知識點叫什麽

  2.知識點用在哪

  3.知識如何實現

一. 進程

  1.進程是什麽

  進程是cpu分配資源的最小單位

  理解:在QQ這個進程裏,傳輸一段文字開啟一個線程,傳輸語音又開啟一個線程。所以運行某個軟件相當於開啟了一個進程。而在這個進程裏,有多個功能來支持QQ正常運行,這些功能又各自占了一條線程。

  一個進程管理著多個線程。(一個進程至少帶一個線程)

  線程和進程的:

    1.單進程單線程:一個人在一個桌子上吃飯

    2.單進程多線程:多個人在一個桌子上吃飯

    3.多進程單線程:多個人每個人在自己桌子上吃飯

技術分享圖片

  2.進程的狀態

  技術分享圖片

  狀態分析:就緒態(運行的條件都已經慢去)執行態(zpu正在執行其他的功能)等待態(等待某些條件滿足,例如一個程序sleep了,此時就處於等待態)

  3.進程的作用

  實現多個任務同時運行,跟多線程功能基本一致。

  

技術分享圖片
 1 import multiprocessing  # 導包
 2 import time
 3 
 4 
 5 def test1():
 6     while True:
 7         print("1------")
 8         time.sleep(1)
 9 
10 
11 def test2():
12     while True:
13 print("2------") 14 time.sleep(1) 15 16 17 def main(): 18 # 創建進程,跟創建多線程一致 19 t1 = multiprocessing.Process(target=test1) 20 t2 = multiprocessing.Process(target=test2) 21 22 # 開啟進程 23 t1.start() 24 t2.start() 25 26 27 if __name__ == __main__: 28 main()
View Code

  4.主進程與子進程

  子進程開啟會復制主進程一樣的代碼

  5.進程和線程的區別

    1.進程浪費資源較大,而且一段代碼進程執行的速度明顯比線程慢。

    2.進程的資源相互獨立不共享,如需通信需要借助一些方法。 線程資源是共享的,但是也有bug,需要加鎖。

    3.進程穩定性好,一個任務掛了,有可能整個進程都掛了,但不會影響其他進程。

二. 進程命令進程

  1.查看進程

  

ps -aux

  技術分享圖片

htop

  技術分享圖片

top

  技術分享圖片

  2.殺死進程

  

kill pid名
kill -9 pid名

  關於這個命令,之前詢問別人其之間的區別,有人講kill -9 pid 是刪除所有與進程相關的,我的疑惑就來了,既然進程之間不相互影響,那麽刪的是什麽相關的呢?一個殺死進程的命令,除了進程還能殺死什麽?

  於是,我上網查了下,再別人的博客下得到了答案:一般不建議使用 kill -9 pid

  kill(默認是-15)的真實含義是, 向進程發送信息,而不是殺死進程。 kill 1234 是向進程1234發送一個SIGTERM信號,有時候 kill 1234 並不能結束這個進程,用kill -9 1234 是真的kill了, kill -9 1234是向1234發送SIGKILL信號

  兩句命令的區別:SIGNKILL(9) 的效果是立即殺死進程. 該信號不能被阻塞, 處理和忽略。 SIGNTERM(15) 的效果是正常退出進程,退出前可以被阻塞或回調處理。並且它是Linux缺省的程序中斷信號。

  一句話, kill是溫柔地殺, kill -9是霸氣地殺

三. 進程的相關知識

  1.pid獲取

技術分享圖片
 1 import multiprocessing
 2 import time
 3 import os
 4 
 5 
 6 def test1():
 7     while True:
 8         print("1-----")
 9         time.sleep(1)
10         print("子進程1",os.getpid())  # 獲取當前進程號
11         print("主進程",os.getppid())  # 獲取主進程的進程號
12 
13 
14 def test2():
15     while True:
16         print("2-----")
17         time.sleep(1)
18         print("子進程2",os.getpid())
19         print("主進程",os.getppid())
20 
21 
22 def main():
23     # 創建進程
24     t1 = multiprocessing.Process(target=test1)
25     t2 = multiprocessing.Process(target=test2)
26 
27     # 開啟進程
28     t1.start()
29     t2.start()
30 
31     print("主進程", os.getpid())  # 獲取主進程的進程號
32 
33 
34 if __name__ == __main__:
35     main()
查看進程pid
主進程 7904
1-----
2-----
子進程1 7560
主進程 7904
1-----
子進程2 6136
主進程 7904
2-----
子進程1 7560
主進程 7904
1-----
子進程2 6136
主進程 7904
2-----
子進程1 7560

  2.子進程中不能使用input()函數,主進程會等到子進程結束而結束,線程是用來執行代碼的,進程使用分配資源的,子進程會復制主進程的資源數據,進程之間的數據不共享,進程的執行時無序的。

  3.傳參

  技術分享圖片

四. 進程與線程的對比

  1.進程是分配資源的單位,線程是程序調度的單位

  2.進程運行必定有一個主線程運行

  3.全局變量:線程共享全局變量,進程不共享全局變量。

  技術分享圖片

  4.加深理解進程與線程的圖片

  技術分享圖片創建

五. 進程間的通訊

  1.使用的技術:Queue隊列

  2.作用:讓進程之間可以通訊  

技術分享圖片
import queue


# 先進先出
q = queue.Queue()
q.put(1)
q.put(2)
q.put(3)


print(q.get())
print(q.get())
print(q.get())

# 後進先出
q = queue.LifoQueue()
q.put(1)
q.put(2)
q.put(3)


print(q.get())
print(q.get())
print(q.get())


# 存儲數據時可設置優先級的隊列

q = queue.PriorityQueue()
# put進入一個元祖,元祖的第一個元素是優先級,數字越小優先級越高
q.put((20, a))
q.put((10, b))
q.put((30, c))


print(q.get())
print(q.get())
print(q.get())
queue的用法

  3.使用方式

  創建隊列放入數據

  技術分享圖片

  獲取數據

  技術分享圖片

  

技術分享圖片
# 定義一個隊列
import multiprocessing

# 定義一個隊列
# 隊列的作用存取數據
# 隊列中的數據取完就沒了
# 隊列中先存先取
import time

queue = multiprocessing.Queue(3)

# 存數據
queue.put_nowait("abc")
queue.put_nowait("abc")
queue.put_nowait("abc")
# queue.put_nowait("abc")

# print(queue.empty())  # 空是有bug

time.sleep(1)

#
print(queue.get_nowait())
print(queue.get_nowait())
# print(queue.get_nowait())
print(queue.empty())  # 空是有bug
# print(queue.get_nowait())
BUG代碼不要用

  4.案例:一個進程讀一個進程寫,在進程創建前創建進程隊列 

技術分享圖片
import multiprocessing
import queue
import time


def write(queue):  # 記得傳參數
    """寫數據的函數"""
    # 通過循環去寫數據
    for temp in range(10):
        queue.put(temp)
        print(temp)
    time.sleep(1)


def read(queue):
    """定義一個讀的函數"""
    data_list = []
     # 通過循環去讀數據
    while True:
        if queue.empty():
            break
        data_list.append(queue.get())
    print(data_list)


def main():
    # 定義一個進程隊列

    queue = multiprocessing.Queue()  # 這個說明沒有限制機器性能

    # 創建兩個進程
    process_write = multiprocessing.Process(target=write, args=(queue,))
    process_read = multiprocessing.Process(target=read, args=(queue,))

    # 開啟線程
    process_write.start()
    process_write.join()  # 控制寫完讀,保證有數據在讀
    process_read.start()


if __name__ == __main__:
    main()
View Code
打印結果:先順序打印0-9 ,停頓1S,在打印0-9的列表。
0
1
2
3
4
5
6
7
8
9
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

  

六. 進程池

  1.什麽是進程池

  python中,進程池內部會維護一個進程序列。當需要時,程序會去進程池中獲取一個進程。  

  如果進程池序列中沒有可供使用的進程,那麽程序就會等待,直到進程池中有可用進程為止

  理解:一個學校有很多教室,不同的班級輪流使用這些教室

  內置的一些方法:   

    apply 從進程池裏取一個進程並同步執行

    apply_async 從進程池裏取出一個進程並異步執行

    terminate 立刻關閉進程池

    join 主進程等待所有子進程執行完畢,必須在close或terminete之後

    close 等待所有進程結束才關閉線程池

  2.進程池的作用

  用來重復利用進程,節省資源

  3.同步執行:放個代碼感受一下,創建3個進程,循環執行5次任務,這時三個進程輪流執行這5個任務,問題來了,這三個進程號是不變的,也就是創建幾個進程池裏數字為幾,最多就可以創建幾個進程,不可不填。感受代碼。

  同步的特點:一個一個執行我們的任務

技術分享圖片
 1 from multiprocessing import Pool
 2 import time
 3 import os
 4 
 5 
 6 def func():
 7     time.sleep(1)
 8     print("run",os.getpid())  # 獲取當前進程號
 9 
10 
11 def main():
12     p1 = Pool(3)  # 設定開啟3個進程池
13     for i in range(5):
14         p1.apply(func)  # 設定異步執行任務
15 
16 
17 if __name__ == __main__:
18     main()
View Code
打印結果:
run 7996
run 9560
run 4184
run 7996
run 9560

  4.異步執行:所有進程同時執行任務 ,apply_async必須和close()必須和join() 這三個必須一起使用,join()要放在for循環之外

  

技術分享圖片
 1 from multiprocessing import Pool
 2 import time
 3 import os
 4 
 5 
 6 def func():
 7     time.sleep(1)
 8     print("run",os.getpid())
 9 
10 
11 def main():
12     p1 = Pool(3)  # 設定開啟3個進程池
13     for i in range(5):
14         p1.apply_async(func)  # 異步,有問題,必須加入join跟close
15 
16     p1.close()  # 關閉進程池,不在接收新的任務
17     p1.join()  # 讓我們的主進程等待進程池完成再結束
18 
19 
20 if __name__ == __main__:
21     main()
View Code
打印結果: 前三行同時出現,停頓1S,後面兩行同時出現
run 10512
run 12788
run 1688
run 10512
run 12788

  案例:復制文件夾

  鏈接:http://blog.csdn.net/chaipp0607/article/details/60779129

  並發:看上去像同時發生的,指應用能夠交替執行不同的任務,註意點,能夠處理多個任務,沒說非要同時。
  並行:指應用能夠同時執行不同的任務,註意點,必須同時。

  兩者區別:一個是交替執行,一個是同時執行。

  

python進程學習