通用線程模塊:multiprocessing
multiprocessing與線程的threading模塊方法、結構類似,但多進程需要對每一個Process對象調用join()方法,以防止該進程成爲殭屍進程
process.PID 可以獲取進程的ID,進程start之前爲空
process.terminate() 強行終止進程(在join()前使用)
process.is_alive() 可以判斷該進程是否還在運行
簡單的啓動進程
process = multiprocessing.Process(target=func, args=(1,2))
process.start()
process.join()
繼承multiprocessing.Process,重寫run()方法
class Task(multiprocessing.Process):
def __init__(self):
pass
def run(self):
'重寫run方法,start啓動的時候會調用run方法'
pass
process = Task()
process.satrt()
process.join()
多進程管理
Pool的參數processes爲線程池的數量,調用join之前,要先調用close() 函數,否則會出錯, close()執行後不會有新的進程不能加入到pool,join函數等待所有子進程結束
pro_list = []
pool = multiprocessing.Pool(processes = 2)
for i in range(5):
res = pool.apply_async(func, args, kwds, callback)
pro_list.append(res)
pool.close()
pool.join()
for pro in pro_list:
#獲取各個進程返回值
print pro.get()
也可以使用 pool.map(func, args_list) 啓動多線程,args_list,爲參數隊列
pool.apply() #阻塞方式(當一個進程運行完成,進程池空出來了後纔會運行新的線程)
pool.apply_async #非阻塞方式(多進程之間來回調度)
鎖
multiprocessing.Lock(),與線程鎖操作基本相同
隊列
進程隊列multiprocessing.Queue(maxsize),與線程隊列操作基本相同
注意:logging日誌模塊只是線程安全的,在多進程中使用,可能會產生錯誤
subprocess模塊
subprocess模塊通常用來執行第三方程序或命令
subprocess.Popen(args, bufsize=0, executable=None,
stdin=None, stdout=None, stderr=None,
preexec_fn=None, close_fds=False, shell=False,
cwd=None, env=None, universal_newlines=False,
startupinfo=None, creationflags=0)
常用參數
args 執行的命令,類型爲字符串時,是所要執行的命令;爲列表或元組時,是命令參數
bufsize 緩存大小
stdin,stdout,stderr 表中輸出、輸入、錯誤:可以爲PIPE 管道,或文件描述符,文件對象
shell 是否爲shell命令True/False (linux下必須,在windows下不要使用)
close_fds 關閉某些文件描述符(不太明白,如果沒有使用該參數,有些文件描述符不會關閉,然後達到最大值,產生錯我)
Popen對象方法和屬性
poll() 檢查是否結束,設置返回值
wait() 等待結束,設置返回值
communicate() 參數是標準輸入,返回標準輸出和標準出錯
send_signal() 發送信號 (主要在unix下有用)
terminate() 終止進程(在kill之前使用,不然kill會失效)
kill() 殺死進程
stdin stdout stderr 參數中指定PIPE時,有用
pid 進程id
returncode 進程返回值
例子:
process = subprocess.Popen(cmd,stdin = subprocess.PIPE, stdout = subprocess.PIPE, stderr = subprocess.PIPE, shell=True ,close_fds=True)
num = 0
timeout = 3600
while process.poll() == None:
if num >= timeout:
try:
process.terminate()
print process.stdout.read()
process.kill()
process.wait()
print "time out"
except:
errmsg = get_err_msg()
log.CmdRun_Logger.error(errmsg)
time.sleep(1)
num+= 1
if process.poll() is not None:
print process.stdout.read()
process.wait()
print 'end'