進程以及狀態
1. 進程
程序:例如xxx.py這是程序,是一個靜態的
進程:一個程序運行起來后,代碼+用到的資源 稱之為進程,它是操作系統分配資源的基本單元。
不僅可以通過線程完成多任務,進程也是可以的
2. 進程的狀態
工作中,任務數往往大於cpu的核數,即一定有一些任務正在執行,而另外一些任務在等待cpu進行執行,因此導致了有了不同的狀態
就緒態:運行的條件都已經慢去,正在等在cpu執行
執行態:cpu正在執行其功能
等待態:等待某些條件滿足,例如一個程序sleep了,此時就處於等待態
linux上進程有5種狀態:
1. 運行(正在運行或在運行隊列中等待)
2. 中斷(休眠中, 受阻, 在等待某個條件的形成或接受到信號)
3. 不可中斷(收到信號不喚醒和不可運行, 進程必須等待直到有中斷發生)
4. 僵死(進程已終止, 但進程描述符存在, 直到父進程調用wait4()系統調用后釋放)
5. 停止(進程收到SIGSTOP, SIGSTP, SIGTIN, SIGTOU信號后停止運行運行)
ps工具標識進程的5種狀態碼:
D 不可中斷 uninterruptible sleep (usually IO)
R 運行 runnable (on run queue)
S 中斷 sleeping
T 停止 traced or stopped
Z 僵死 a defunct ("zombie") process
線程與進程
線程與進程是操作系統里面的術語,簡單來講,每一個應用程序都有一個自己的進程。
操作系統會為這些進程分配一些執行資源,例如內存空間等。
在進程中,又可以創建一些線程,他們共享這些內存空間,並由操作系統調用,
以便並行計算。
32位系統受限於總線寬度,單個進程最多能夠訪問的地址空間
只有4G,利用物理地址擴展(PAE)
技術,可以讓CPU訪問超過4G內存。但是在單個進程還是只能訪問4G
空間,PAE的優勢是可以讓不同進程累計使用的內存超過4G。
在個人電腦上,還是建議使用64位系統,便於使用大內存
提升程序的運行性能。
多線程編程
線程的狀態
創建線程之后,線程並不是始終保持一個狀態。其狀態大概如下:
- New 創建。
- Runnable 就緒。等待調度
- Running 運行。
- Blocked 阻塞。阻塞可能在 Wait Locked Sleeping
- Dead 消亡
線程的類型
線程有着不同的狀態,也有不同的類型。大致可分為:
- 主線程
- 子線程
- 守護線程(后台線程)
- 前台線程
python的GIL
GIL即全局解釋器鎖,它使得python的多線程無法充分利用
多核的優勢,但是對於I/O操作頻繁的爬蟲之類的程序,
利用多線程帶來的優勢還是很明顯的。
如果要利用多核優勢,還是用多進程吧。
https://tracholar.github.io/wiki/python/python-multiprocessing-tutorial.html
可以直接使用top命令后,查看%MEM的內容。可以選擇按進程查看或者按用戶查看,如想查看oracle用戶的進程內存使用情況的話可以使用如下的命令:
(1)top
top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源占用狀況,類似於Windows的任務管理器
可以直接使用top命令后,查看%MEM的內容。可以選擇按進程查看或者按用戶查看,如想查看oracle用戶的進程內存使用情況的話可以使用如下的命令:
$ top -u oracle
內容解釋:
PID:進程的ID
USER:進程所有者
PR:進程的優先級別,越小越優先被執行
NInice:值
VIRT:進程占用的虛擬內存
RES:進程占用的物理內存
SHR:進程使用的共享內存
S:進程的狀態。S表示休眠,R表示正在運行,Z表示僵死狀態,N表示該進程優先值為負數
%CPU:進程占用CPU的使用率
%MEM:進程使用的物理內存和總內存的百分比
TIME+:該進程啟動后占用的總的CPU時間,即占用CPU使用時間的累加值。
COMMAND:進程啟動命令名稱
常用的命令:
P:按%CPU使用率排行
T:按MITE+排行
M:按%MEM排行
(2)pmap
可以根據進程查看進程相關信息占用的內存情況,(進程號可以通過ps查看)如下所示:
$ pmap -d 14596
進程
python中的多線程其實並不是真正的多線程,如果想要充分地使用多核CPU的資源,在python中大部分情況需要使用多進程。
Python提供了非常好用的多進程包multiprocessing,只需要定義一個函數,Python會完成其他所有事情。
借助這個包,可以輕松完成從單進程到並發執行的轉換。
multiprocessing支持子進程、通信和共享數據、執行不同形式的同步,提供了Process、Queue、Pipe、Lock等組件。
---------------------
1.https://segmentfault.com/q/1010000011117956
該題主描述了同樣的問題。我覺得比較有意義的回答是這個
multiprocessing.Pool 只是用來啟動多個進程而不是在每個core上啟動一個進程。換句話說Python解釋器本身不會去在每個core或者processor去做負載均衡。這個是由操作系統決定的。
如果你的工作特別的計算密集型的話,操作系統確實會分配更多的core,但這也不是Python或者代碼所能控制的或指定的。
multiprocessing.Pool(num)中的num可以很小也可以很大,比如I/O密集型的操作,這個值完全可以大於cpu的個數。
硬件系統的資源分配是由操作系統決定的,如果你希望每個core都在工作,就需要更多的從操作系統出發了~
在后續的回答中給出了一個stackoverflow里面的此類問題介紹
實驗
實驗環境:4C8G
1.工作任務設置成計算密集型
四個任務被均分到四個核上,順利運行
2.計算密集型+每個進程小內存消耗
四個任務被均分到四個核上,順利運行
3.計算密集型+每個進程大內存消耗
計算機卡死
---------------------
2018-12-18 今天好像找到問題了的原因了:
問題1:
因為進程間不同享全局變量,所以我定義的全局變量df_list,在最后依舊是初始狀態df_list = [ ]
實例:
# -*- coding:utf-8 -*- from multiprocessing import Process import os import time nums = [11, 22] def work1(): """子進程要執行的代碼""" print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums)) for i in range(3): nums.append(i) time.sleep(1) print("in process1 pid=%d ,nums=%s" % (os.getpid(), nums)) def work2(): """子進程要執行的代碼""" print("in process2 pid=%d ,nums=%s" % (os.getpid(), nums)) if __name__ == '__main__': p1 = Process(target=work1) p1.start() p1.join() p2 = Process(target=work2) p2.start()
問題2:問題在於,多進程可以啟動,但是,所有子進程都處於等待狀態
可能是資源的問題。內存資源不夠,所以無法同時運行,只能等待!這只是猜想了。
參考:https://blog.csdn.net/u013735511/article/details/80079373
https://blog.csdn.net/xlengji/article/details/81165370