python 多進程,實際上都沒有運行,sleep


 進程以及狀態

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


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM