python 进程相关 (八)

通用线程模块: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'


你可能感兴趣的:(python,知识点)