创建进程模块的方法
os.system
os.system是最简单创建进程的方法,参数只有一个,就是要执行的命令,如"dir",就类似于在cmd中输入的命令。
os.exec系列函数一共有8个。查看
os.fork
os.fork函数调用系统API并创建子进程,但是fork函数在windows中并不存在,在linux和mac上可以正常使用。
subprocess模块
调用外部命令,而那些外部命令就是这些函数的参数,subprocess模块比前3种模块提供了更多的方法来调用外部命令。
所有的方法种args是必传的参数,它可以是字符串或者序列类型。默认执行的程序应该是序列的第一个字段,单个字符串的话,解析依赖于平台。在Unix系统中,如果args是一个字符串,那么这个字符串会解释成被执行程序的名字或路径,这种情况只能用在不需要传参数的程序上。
这里介绍下与os.system类型的函数功能:接收参数运行命令并返回命令。他就是subprocess.call函数,但他返回的是返回命令的退出码(为0则表示运行成功)
个人觉得:运行命令参数的话,他比os.system繁琐多了。
multiprocessing.Process
multiprocessing创建的是子进程,所以可以有效地避免全局解释器锁和有效地利用多核CPU的性能。
multiprocessing.Process对象和threading.Thread的使用方法大致一样。
多进程之间的通信
multiprocessing.Queue可以实现进程之间的通信,而多线程中其实也是有个Queue对象,这里的Queue对象的作用是线程安全。
线程之间可以共享变量,但是进程之间不会共享变量。对然multiprocessing.Queue的方法和queue.Queue方法一摸一样,但是在创建的时候需要把Queue对象传递给进程,这样才能正确的让主进程获取子进程的数据,否则主进程的Queue内一直都是空的。
线程池
使用的虽然还是multiprocessing模块,但它的dump类吧,可以进行多线程的创建,并且通过该类的dump.pool(processes=线程池的数量),该类的作用是复制了multiprocessing模块的API,但多线程实现线程池的方法和多进程实现进程池的方法一样。线程池也可以用map()来映射函数。
import multiprocessing.dummy # 该模块作用是复制了multiprocessing模块的API
import time
# 多线程实现线程池的方法和多进程实现进程池的方法一样
def process_func(process_id):
print("process id %d start" % process_id)
time.sleep(3)
print("process id %d end"% process_id)
def main():
#虽然参数叫processes但是实际创建的是线程
pool = multiprocessing.dummy.Pool(processes=3)
for i in range(10):
# 向进程池中添加要执行的任务
# apply_asyns这个函数的作用是什么,asyns经常在服务器中碰到这个词;写错了,报错,是async
pool.apply_async(process_func,args=(i,))
pool.close()
pool.join()
if __name__ == "__main__":
main()