❶ 簡述python進程,線程和協程的區別
協程多與線程進行比較
1) 一個線程可以多個協程,一個進程也可以單獨擁有多個協程,這樣python中則能使用多核CPU。
2) 線程進程都是同步機制,而協程則是非同步
3) 協程能保留上一次調用時的狀態,每次過程重入時,就相當於進入上一次調用的狀態
❷ python subprocess.popen 怎麼獲取到tty
def getmask(): command='for /f "delims=: tokens=2" %i in (\'ipconfig ^| findstr 子網掩碼\') do echo %i' Popen(command,shell=True)
❸ python 怎麼查看signal
信號(signal)--進程之間通訊的方式,是一種軟體中斷。一個進程一旦接受到信號就會打斷原來的程序執行流程來處理信號。
幾個常用信號:
SIGINT 終止進程 中斷進程 (control+c)
SIGTERM 終止進程 軟體終止信號
SIGKILL 終止進程 殺死進程
SIGALRM 鬧鍾信號
進程結束信號 SIGTERM和SIGKILL的區別
SIGTERM比較友好,進程能捕捉這個信號,根據您的需要來關閉程序。在關閉程序之前,您可以結束打開的記錄文件和完成正在做的任務。在某些情況下,假如進程正在進行作業而且不能中斷,那麼進程可以忽略這個SIGTERM信號。
對於SIGKILL信號,進程是不能忽略的。這是一個 「我不管您在做什麼,立刻停止」的信號。假如您發送SIGKILL信號給進程,Linux就將進程停止在那裡。
發送信號一般有兩種原因:
1(被動式) 內核檢測到一個系統事件.例如子進程退出會像父進程發送SIGCHLD信號.鍵盤按下control+c會發送SIGINT信號
2(主動式) 通過系統調用kill來向指定進程發送信號
補充:
POSIX.1中列出的信號:
信號 值 處理動作 發出信號的原因
----------------------------------------------------------------------
SIGHUP 1 A 終端掛起或者控制進程終止
SIGINT 2 A 鍵盤中斷(如break鍵被按下)
SIGQUIT 3 C 鍵盤的退出鍵被按下
SIGILL 4 C 非法指令
SIGABRT 6 C 由abort(3)發出的退出指令
SIGFPE 8 C 浮點異常
SIGKILL 9 AEF Kill信號
SIGSEGV 11 C 無效的內存引用
SIGPIPE 13 A 管道破裂: 寫一個沒有讀埠的管道
SIGALRM 14 A 由alarm(2)發出的信號
SIGTERM 15 A 終止信號
SIGUSR1 30,10,16 A 用戶自定義信號1
SIGUSR2 31,12,17 A 用戶自定義信號2
SIGCHLD 20,17,18 B 子進程結束信號
SIGCONT 19,18,25 進程繼續(曾被停止的進程)
SIGSTOP 17,19,23 DEF 終止進程
SIGTSTP 18,20,24 D 控制終端(tty)上按下停止鍵
SIGTTIN 21,21,26 D 後台進程企圖從控制終端讀
SIGTTOU 22,22,27 D 後台進程企圖從控制終端寫
處理動作一項中的字母含義如下:
A 預設的動作是終止進程
B 預設的動作是忽略此信號
C 預設的動作是終止進程並進行內核映像轉儲(mp core)
D 預設的動作是停止進程
E 信號不能被捕獲
F 信號不能被忽略
鍵盤和shell的交互:
Ctrl-c Kill foreground process 常用 ;送SIGINT信號,默認進程會結束,但是進程自己可以重定義收到這個信號的行為。
Ctrl-z Suspend foreground process;送SIGSTOP信號,進程只是被停止,再送SIGCONT信號,進程繼續運行。
Ctrl-d Terminate input, or exit shell 常用 有時也會使程序退出,例如沒有參數的cat命令,從終端讀一行顯示一行,知道Ctrl+D終結輸入並終結進程;不是發送信號,而是表示一個特殊的二進制值,表示 EOF。
Ctrl-s Suspend output
Ctrl-q Resume output
Ctrl-o Discard output
Ctrl-l Clear screen
控制字元都是可以用(stty命令)更改的。可以用stty -a看看終端配置。
有些信號不能被屏蔽,比如中斷,還應該有殺死進程的信號,要不然內核怎麼做操作系統中的老大。實際上,SIGKILL和SIGSTOP信號是不能被屏蔽或阻止的,他們的默認動作總是會被執行的
❹ Python中的進程是什麼
什麼是進程
進程(Process)是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。在早期面向進程設計的計算機結構中,進程是程序的基本執行實體;在當代面向線程設計的計算機結構中,進程是線程的容器。程序是指令、數據及其組織形式的描述,進程是程序的實體。
狹義定義:進程是正在運行的程序的實例(an instance of a computer program that is being executed)。
廣義定義:進程是一個具有一定獨立功能的程序關於某個數據集合的一次運行活動。它是操作系統動態執行的基本單元,在傳統的操作系統中,進程既是基本的分配單元,也是基本的執行單元。
進程的概念主要有兩點:第一,進程是一個實體。每一個進程都有它自己的地址空間,一般情況下,包括文本區域(text region)、數據區域(data region)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變數和進程執行期間使用的動態分配的內存;堆棧區域存儲著活動過程調用的指令和本地變數。第二,進程是一個「執行中的程序」。程序是一個沒有生命的實體,只有處理器賦予程序生命時(操作系統執行之),它才能成為一個活動的實體,我們稱其為進程。
相關推薦:《Python視頻教程》
程序和進程的關系
編寫完畢的代碼,在沒有運?的時候,稱之為程序。
正在運行著的代碼,就成為進程。
進程除了包含代碼以外還有需要運行的環境等所以和程序是有區別的。
相關推薦:
Python中的多進程是什麼
❺ python怎麼實現一個進程
想要充分利用多核CPU資源,Python中大部分情況下都需要使用多進程,Python中提供了multiprocessing這個包實現多進程。multiprocessing支持子進程、進程間的同步與通信,提供了Process、Queue、Pipe、Lock等組件。
開辟子進程
multiprocessing中提供了Process類來生成進程實例
Process([group [, target [, name [, args [, kwargs]]]]])1
group分組,實際上不使用
target表示調用對象,你可以傳入方法的名字
args表示給調用對象以元組的形式提供參數,比如target是函數a,他有兩個參數m,n,那麼該參數為args=(m, n)即可
kwargs表示調用對象的字典
name是別名,相當於給這個進程取一個名字
先來個小例子:
運行結果:
Parent process run. subProcess is 30196
Parent process end,Mon Mar 27 11:20:21 2017
subProcess 30196 run, Mon Mar 27 11:20:21 2017
subProcess 30196 run, Mon Mar 27 11:20:23 2017
subProcess 30196 run, Mon Mar 27 11:20:25 2017
根據運行結果可知,父進程運行結束後子進程仍然還在運行,這可能造成僵屍( zombie)進程。
通常情況下,當子進程終結時,它會通知父進程,清空自己所佔據的內存,並在內核里留下自己的退出信息。父進程在得知子進程終結時,會從內核中取出子進程的退出信息。但是,如果父進程早於子進程終結,這可能造成子進程的退出信息滯留在內核中,子進程成為僵屍(zombie)進程。當大量僵屍進程積累時,內存空間會被擠占。
有什麼辦法可以避免僵屍進程呢?
這里介紹進程的一個屬性 deamon,當其值為TRUE時,其父進程結束,該進程也直接終止運行(即使還沒運行完)。
所以給上面的程序加上p.deamon = true,看看效果。
執行結果:
Parent process run. subProcess is 31856
Parent process end,Mon Mar 27 11:40:10 2017
這是問題又來了,子進程並沒有執行完,這不是所期望的結果。有沒辦法將子進程執行完後才讓父進程結束呢?
這里引入p.join()方法,它使子進程執行結束後,父進程才執行之後的代碼
執行結果:
subProcess 32076 run, Mon Mar 27 11:46:07 2017
subProcess 32076 run, Mon Mar 27 11:46:09 2017
subProcess 32076 run, Mon Mar 27 11:46:11 2017
Parent process run. subProcess is 32076
Parent process end,Mon Mar 27 11:46:13 2017
這樣所有的進程就能順利的執行了。
將進程定義成類
通過繼承Process類,來自定義進程類,實現run方法。實例p通過調用p.start()時自動調用run方法。
如下:
執行結果和上一個例子相同。
創建多個進程
很多時候系統都需要創建多個進程以提高CPU的利用率,當數量較少時,可以手動生成一個個Process實例。當進程數量很多時,或許可以利用循環,但是這需要程序員手動管理系統中並發進程的數量,有時會很麻煩。這時進程池Pool就可以發揮其功效了。可以通過傳遞參數限制並發進程的數量,默認值為CPU的核數。
直接上例子:
執行結果:
開頭部分
Run the main process (30920).
Waiting for all subprocesses done …
Run child process Process0 (32396)
Run child process Process3 (25392)
Run child process Process1 (28732)
Run child process Process2 (32436)
末尾部分:
Run child process Process15 (25880)
All subprocesses done
All process last 2.49 seconds.
相關說明:
這里進程池對並發進程的限制數量為8個,而程序運行時會產生16個進程,進程池將自動管理系統內進程的並發數量,其餘進程將會在隊列中等待。限制並發數量是因為,系統中並發的進程不是越多越好,並發進程太多,可能使CPU大部分的時間用於進程調度,而不是執行有效的計算。
採用多進程並發技術時,就單個處理機而言,其對進程的執行是串列的。但具體某個時刻哪個進程獲得CPU資源而執行是不可預知的(如執行結果的開頭部分,各進程的執行順序不定),這就體現了進程的非同步性。
如果單個程序執行14次run_proc函數,那麼它會需要至少16秒,通過進程的並發,這里只需要2.49秒,可見並發的優勢。
❻ Python中進程與線程的區別是什麼
Num01–>線程
線程是操作系統中能夠進行運算調度的最小單位。它被包含在進程之中,是進程中的實際運作單位。
一個線程指的是進程中一個單一順序的控制流。
一個進程中可以並發多條線程,每條線程並行執行不同的任務。
Num02–>進程
進程就是一個程序在一個數據集上的一次動態執行過程。
進程有以下三部分組成:
1,程序:我們編寫的程序用來描述進程要完成哪些功能以及如何完成。
2,數據集:數據集則是程序在執行過程中需要的資源,比如圖片、音視頻、文件等。
3,進程式控制制塊:進程式控制制塊是用來記錄進程的外部特徵,描述進程的執行變化過程,系統可以用它來控制和管理進程,它是系統感知進程存在的唯一標記。
Num03–>進程和線程的區別:
1、運行方式不同:
進程不能單獨執行,它只是資源的集合。
進程要操作CPU,必須要先創建一個線程。
所有在同一個進程里的線程,是同享同一塊進程所佔的內存空間。
2,關系
進程中第一個線程是主線程,主線程可以創建其他線程;其他線程也可以創建線程;線程之間是平等的。
進程有父進程和子進程,獨立的內存空間,唯一的標識符:pid。
3,速度
啟動線程比啟動進程快。
運行線程和運行進程速度上是一樣的,沒有可比性。
線程共享內存空間,進程的內存是獨立的。
4,創建
父進程生成子進程,相當於復制一份內存空間,進程之間不能直接訪問
創建新線程很簡單,創建新進程需要對父進程進行一次復制。
一個線程可以控制和操作同級線程里的其他線程,但是進程只能操作子進程。
5,交互
同一個進程里的線程之間可以直接訪問。
兩個進程想通信必須通過一個中間代理來實現。
相關推薦:《Python視頻教程》
Num04–>幾個常見的概念
1,什麼的並發和並行?
並發:微觀上CPU輪流執行,宏觀上用戶看到同時執行。因為cpu切換任務非常快。
並行:是指系統真正具有同時處理多個任務(動作)的能力。
2,同步、非同步和輪詢的區別?
同步任務:B一直等著A,等A完成之後,B再執行任務。(打電話案例)
輪詢任務:B沒有一直等待A,B過一會來問一下A,過一會問下A
非同步任務:B不需要一直等著A, B先做其他事情,等A完成後A通知B。(發簡訊案例)
Num05–>進程和線程的優缺點比較
首先,要實現多任務,通常我們會設計Master-Worker模式,Master負責分配任務,Worker負責執行任務,因此,多任務環境下,通常是一個Master,多個Worker。
如果用多進程實現Master-Worker,主進程就是Master,其他進程就是Worker。
如果用多線程實現Master-Worker,主線程就是Master,其他線程就是Worker。
多進程模式最大的優點就是穩定性高,因為一個子進程崩潰了,不會影響主進程和其他子進程。(當然主進程掛了所有進程就全掛了,但是Master進程只負責分配任務,掛掉的概率低)著名的Apache最早就是採用多進程模式。
多進程模式的缺點是創建進程的代價大,在Unix/Linux系統下,用fork調用還行,在Windows下創建進程開銷巨大。另外,操作系統能同時運行的進程數也是有限的,在內存和CPU的限制下,如果有幾千個進程同時運行,操作系統連調度都會成問題。
多線程模式通常比多進程快一點,但是也快不到哪去,而且,多線程模式致命的缺點就是任何一個線程掛掉都可能直接造成整個進程崩潰,因為所有線程共享進程的內存。在Windows上,如果一個線程執行的代碼出了問題,你經常可以看到這樣的提示:「該程序執行了非法操作,即將關閉」,其實往往是某個線程出了問題,但是操作系統會強制結束整個進程。
在Windows下,多線程的效率比多進程要高,所以微軟的IIS伺服器默認採用多線程模式。由於多線程存在穩定性的問題,IIS的穩定性就不如Apache。為了緩解這個問題,IIS和Apache現在又有多進程+多線程的混合模式,真是把問題越搞越復雜。
Num06–>計算密集型任務和IO密集型任務
是否採用多任務的第二個考慮是任務的類型。我們可以把任務分為計算密集型和IO密集型。
第一種:計算密集型任務的特點是要進行大量的計算,消耗CPU資源,比如計算圓周率、對視頻進行高清解碼等等,全靠CPU的運算能力。這種計算密集型任務雖然也可以用多任務完成,但是任務越多,花在任務切換的時間就越多,CPU執行任務的效率就越低,所以,要最高效地利用CPU,計算密集型任務同時進行的數量應當等於CPU的核心數。
計算密集型任務由於主要消耗CPU資源,因此,代碼運行效率至關重要。Python這樣的腳本語言運行效率很低,完全不適合計算密集型任務。對於計算密集型任務,最好用C語言編寫。
第二種:任務的類型是IO密集型,涉及到網路、磁碟IO的任務都是IO密集型任務,這類任務的特點是CPU消耗很少,任務的大部分時間都在等待IO操作完成(因為IO的速度遠遠低於CPU和內存的速度)。對於IO密集型任務,任務越多,CPU效率越高,但也有一個限度。常見的大部分任務都是IO密集型任務,比如Web應用。
IO密集型任務執行期間,99%的時間都花在IO上,花在CPU上的時間很少,因此,用運行速度極快的C語言替換用Python這樣運行速度極低的腳本語言,完全無法提升運行效率。對於IO密集型任務,最合適的語言就是開發效率最高(代碼量最少)的語言,腳本語言是首選,C語言最差。
相關推薦:
Python中的進程是什麼
❼ python 多進程問題
兩個進程如果要同時運行,star函數挨著一起寫
❽ python進程間通信怎麼理解
在2.6才開始使用
multiprocessing 是一個使用方法類似threading模塊的進程模塊。允許程序員做並行開發。並且可以在UNIX和Windows下運行。
通過創建一個Process 類型並且通過調用call()方法spawn一個進程。
一個比較簡單的例子:
#!/usr/bin/env python
from multiprocessing import Process
import time
def f(name):
time.sleep(1)
print 'hello ',name
print os.getppid() #取得父進程ID
print os.getpid() #取得進程ID
process_list = []
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
進程間通信:
有兩種主要的方式:Queue、Pipe
1- Queue類幾乎就是Queue.Queue的復制,示例:
#!/usr/bin/env python
from multiprocessing import Process,Queue
import time
def f(name):
time.sleep(1)
q.put(['hello'+str(name)])
process_list = []
q = Queue()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
for i in range(10):
print q.get()
2- Pipe 管道
#!/usr/bin/env python
from multiprocessing import Process,Pipe
import time
import os
def f(conn,name):
time.sleep(1)
conn.send(['hello'+str(name)])
print os.getppid(),'-----------',os.getpid()
process_list = []
parent_conn,child_conn = Pipe()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(child_conn,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
for p in range(10):
print parent_conn.recv()
Pipe()返回兩個連接類,代表兩個方向。如果兩個進程在管道的兩邊同時讀或同時寫,會有可能造成corruption.
進程間同步
multiprocessing contains equivalents of all the synchronization primitives from threading.
例如,可以加一個鎖,以使某一時刻只有一個進程print
#!/usr/bin/env python
from multiprocessing import Process,Lock
import time
import os
def f(name):
lock.acquire()
time.sleep(1)
print 'hello--'+str(name)
print os.getppid(),'-----------',os.getpid()
lock.release()
process_list = []
lock = Lock()
if __name__ == '__main__':
for i in range(10):
p = Process(target=f,args=(i,))
p.start()
process_list.append(p)
for j in process_list:
j.join()
進程間共享狀態 Sharing state between processes
當然盡最大可能防止使用共享狀態,但最終有可能會使用到.
1-共享內存
可以通過使用Value或者Array把數據存儲在一個共享的內存表中
#!/usr/bin/env python
from multiprocessing import Process,Value,Array
import time
import os
def f(n,a,name):
time.sleep(1)
n.value = name * name
for i in range(len(a)):
a[i] = -i
process_list = []
if __name__ == '__main__':
num = Value('d',0.0)
arr = Array('i',range(10))
for i in range(10):
p = Process(target=f,args=(num,arr,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print num.value
print arr[:]
輸出:
jimin@Jimin:~/projects$ python pp.py
81.0
[0, -1, -2, -3, -4, -5, -6, -7, -8, -9]
'd'和'i'參數是num和arr用來設置類型,d表示一個雙精浮點類型,i表示一個帶符號的整型。
更加靈活的共享內存可以使用multiprocessing.sharectypes模塊
Server process
Manager()返回一個manager類型,控制一個server process,可以允許其它進程通過代理復制一些python objects
支持list,dict,Namespace,Lock,Semaphore,BoundedSemaphore,Condition,Event,Queue,Value,Array
例如:
#!/usr/bin/env python
from multiprocessing import Process,Manager
import time
import os
def f(d,name):
time.sleep(1)
d[name] = name * name
print d
process_list = []
if __name__ == '__main__':
manager = Manager()
d = manager.dict()
for i in range(10):
p = Process(target=f,args=(d,i))
p.start()
process_list.append(p)
for j in process_list:
j.join()
print d
輸出結果:
{2: 4}
{2: 4, 3: 9}
{2: 4, 3: 9, 4: 16}
{1: 1, 2: 4, 3: 9, 4: 16}
{1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 8: 64}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}
Server process managers比共享內存方法更加的靈活,一個單獨的manager可以被同一網路的不同計算機的多個進程共享。
比共享內存更加的緩慢
使用工作池Using a pool of workers
Pool類代表 a pool of worker processes.
It has methods which allows tasks to be offloaded to the worker processes in a few different ways.
❾ Python中進程和線程的區別詳解
什麼是進程(Process):普通的解釋就是,進程是程序的一次執行,而什麼是線程(Thread),線程可以理解為進程中的執行的一段程序片段。在一個多任務環境中下面的概念可以幫助我們理解兩者間的差別:進程間是獨立的,這表現在內存空間,上下文環境;線程運行在進程空間內。 一般來講(不使用特殊技術)進程是無法突破進程邊界存取其他進程內的存儲空間;而線程由於處於進程空間內,所以同一進程所產生的線程共享同一內存空間。同一進程中的兩段代碼不能夠同時執行,除非引入線程。線程是屬於進程的,當進程退出時該進程所產生的線程都會被強制退出並清除。線程佔用的資源要少於進程所佔用的資源。進程和線程都可以有優先順序。在線程系統中進程也是一個線程。可以將進程理解為一個程序的第一個線程。
線程是指進程內的一個執行單元,也是進程內的可調度實體.與進程的區別:(1)地址空間:進程內的一個執行單元;進程至少有一個線程;它們共享進程的地址空間;而進程有自己獨立的地址空間;(2)進程是資源分配和擁有的單位,同一個進程內的線程共享進程的資源(3)線程是處理器調度的基本單位,但進程不是.(4)二者均可並發執行.