python的multiprocessing模块是用来创建多进程的,下面对multiprocessing总结一下使用记录。

multiprocessing创建多进程在windows和linux系统下的对比

fork()

  1. import ospid = os.fork() # 创建一个子进程if pid == 0:    print('这是子进程')    print(os.getpid(),os.getppid())else:    print('这是父进程')    print(os.getpid())os.wait() # 等待子进程结束释放资源
  • fork函数被调用后会返回两次,pid为0的代表子进程,其他返回子进程的id号表示父进程。

  • getpid和getppid函数可以获取本进程和父进程的id号;

fork方式的缺点:

  1. 兼容性差,只能在类linux系统下使用,windows系统不可使用;

  2. 扩展性差,当需要多条进程的时候,进程管理变得很复杂;

  3. 会产生“孤儿”进程和“僵尸”进程,需要手动回收资源。

优点:

是系统自带的接近低层的创建方式,运行效率高。

Process创建进程

  • 创建方式一:

  1. from multiprocessing import Queue, Processimport osdef test():
  2.     time.sleep(2)
  3.     print('this is process {}'.format(os.getpid()))if __name__ == '__main__':
  4.     p = Process(target=test)
  5.     p.start() # 子进程 开始执行
  6.     p.join() # 等待子进程结束
  7.     print('ths peocess is ended')
  • 创建方式二:

  1. from multiprocessing import Queue, Processimport osclass MyProcess(Process):
  2.  
  3.     def run(self):
  4.         time.sleep(2)
  5.         print('this is process {}'.format(os.getpid()))    def __del__(self):
  6.         print('del the process {}'.format(os.getpid()))if __name__ == '__main__':
  7.     p = MyProcess()
  8.     p.start()
  9.     print('ths process is ended')# 结果:ths process is ended
  10. this is process 7600del the process 7600del the process 12304

说明:

  • Process对象可以创建进程,但Process对象不是进程,其删除与否与系统资源是否被回收没有直接的关系。

  • 上例看到del方法被调用了两次,Process进程创建时,子进程会将主进程的Process对象完全复制一份,这样在主进程和子进程各有一个Process对象,但是p1.start()启动的是子进程,主进程中的Process对象作为一个静态对象存在。

  • 主进程执行完毕后会默认等待子进程结束后回收资源,不需要手动回收资源;

  • join()函数用来控制子进程结束的顺序,主进程会阻塞等待子进程结束,其内部也有一个清除僵尸进程的函数,可以回收资源;

  • 当子进程执行完毕后,会产生一个僵尸进程,其会被join函数回收,或者再有一条进程开启,start函数也会回收僵尸进程,所以不一定需要写join函数。

  • windows系统在子进程结束后会立即自动清除子进程的Process对象,而linux系统子进程的Process对象如果没有join函数和start函数的话会在主进程结束后统一清除。

Process对象分析

  1. class Process(object):
  2.     def __init__(self, group=None, target=None, name=None, args=(), kwargs={}):
  3.         pass
  4. # Process对象是python用来创建进程的类
  5. group:扩展保留字段;
  6. target:目标代码,一般是我们需要创建进程执行的目标函数。
  7. name:进程的名字,如果不指定会自动分配一个;
  8. args:目标函数的普通参数;
  9. kwargs:目标函数的键值对参数;
  10.  
  11. # 方法
  12. start():创建一个子进程并执行,该方法一个Process实例只能执行一次,其会创建一个进程执行该类的run方法。
  13. run():子进程需要执行的代码;
  14. join():主进程阻塞等待子进程直到子进程结束才继续执行,可以设置等待超时时间timeout.
  15. terminate():使活着的进程终止;
  16. is_alive():判断子进程是否还活着。

进程池Pool

如果需要创建大量的进程,就需要使用Pool了。

  1. from multiprocessing import Queue, Process, Poolimport osdef test():
  2.     time.sleep(2)
  3.     print('this is process {}'.format(os.getpid()))def get_pool(n=5):
  4.     p = Pool(n) # 设置进程池的大小
  5.     for i in range(10):
  6.         p.apply_async(test)
  7.     p.close() # 关闭进程池
  8.     p.join()if __name__ == '__main__':
  9.     get_pool()
  10.     print('ths process is ended')

分析:厦门厦工叉车怎么样?

  • 如上,进程池Pool被创建出来后,即使实际需要创建的进程数远远大于进程池的最大上限,p1.apply_async(test)代码依旧会不停的执行,并不会停下等待;相当于向进程池提交了10个请求,会被放到一个队列中;

  • 当执行完p1 = Pool(5)这条代码后,5条进程已经被创建出来了,只是还没有为他们各自分配任务,也就是说,无论有多少任务,实际的进程数只有5条,计算机每次最多5条进程并行。

  • 当Pool中有进程任务执行完毕后,这条进程资源会被释放,pool会按先进先出的原则取出一个新的请求给空闲的进程继续执行;

  • 当Pool所有的进程任务完成后,会产生5个僵尸进程,如果主线程不结束,系统不会自动回收资源,需要调用join函数去回收。

  • join函数是主进程等待子进程结束回收系统资源的,如果没有join,主程序退出后不管子进程有没有结束都会被强制杀死;

  • 创建Pool池时,如果不指定进程最大数量,默认创建的进程数为系统的内核数量.

Pool对象分析

  1. class Pool(object):
  2.     def __init__(self, processes=None, initializer=None, initargs=(),
  3.                  maxtasksperchild=None, context=None):
  4.         pass
  5. # 初始化参数
  6. processes:进程池的大小,默认cpu内核的数量
  7. initializer:创建进程执行的目标函数,其会按照进程池的大小创建相应个数的进程;
  8. initargs:目标函数的参数
  9. context:代码的上下文
  10.  
  11. # 方法
  12. apply():使用阻塞方式调用func;
  13. apply_async():使用非阻塞方式条用func
  14. close():关闭Pool,使其不再接受新的任务;
  15. terminate():不管任务是否完成,立即终止;
  16. join():主进程阻塞,等待子进程的退出,必须在close()后面使用;
  17. map(self, func, iterable, chunksize=None):多进程执行一个函数,传入不同的参数;
  18. starmap(self, func, iterable, chunksize=None):和map类似,但iterable参数可解压缩;
  19. starmap_async(self, func, iterable, chunksize=None, callback=None,error_callback=None):使用异步的方式的starmapcallback为返回后的处理函数
  20. map_async(self, func, iterable, chunksize=None, callback=None,error_callback=None):异步方式的map
  • 实例

  1. from multiprocessing import Poolimport osdef test(n):
  2.     time.sleep(1)
  3.     print('this is process {}'.format(os.getpid()))    return ndef test1(n, m):
  4.     print(n, m)
  5.     print('this is process {}'.format(os.getpid()))def back_func(values): # 多进程执行完毕会返回所有的结果的列表
  6.     print(values)def back_func_err(values): # 多进程执行完毕会返回所有错误的列表
  7.     print(values)def get_pool(n=5):
  8.     p = Pool(n)    # p.map(test, (i for i in range(10))) # 阻塞式多进程执行
  9.     # p.starmap(test1, zip([1,2,3],[3,4,5])) # 阻塞式多进程执行多参数函数
  10.     # 异步多进程执行函数
  11.     p.map_async(test, (for i in range(5)), callback=back_func, error_callback=back_func_err)    # 异步多进程执行多参数函数
  12.     p.starmap_async(test1, zip([1,2,3],[3,4,5]), callback=back_func, error_callback=back_func_err)
  13.     print('-----')
  14.     p.close()
  15.     p.join()if __name__ == '__main__':
  16.     get_pool()
  17.     print('ths process is ended')

进程锁

进程虽然不像线程那样共享内存的数据,而是每个进程有单独的内存,但多进程也是共享文件系统的,即硬盘系统;当多进程同时写入文件操作时,可能造成数据的破坏,因此进程也存在同步锁。

  1. from multiprocessing import Pool, Lockmuex = Lock()def test():    if muex.acquire():
  2.         f = open('./test_pro.txt', 'r+', encoding='utf-8')
  3.         x = f.read()        if not x:
  4.             f.write('0')        else:
  5.             f.seek(0)
  6.             f.write(str(int(x)+1))
  7.         f.close()
  8.         muex.release()if __name__ == '__main__':
  9.     p = Pool(5)    for i in range(10):
  10.         p.apply_async(test)
  11.     p.close()
  12.     p.join()    with open('./test_pro.txt', 'r+', encoding='utf-8') as f:
  13.         print(f.read())

进程锁可以保证文件系统的安全,但是它使得并行变成了串行,效率下降了,也可能造成死锁问题,一般避免用锁机制。

python之multiprocessing创建进程的更多相关文章

  1. python的multiprocessing模块进程创建、资源回收-Process,Pool

    python的multiprocessing有两种创建进程的方式,每种创建方式和进程资源的回收都不太相同,下面分别针对Process,Pool及系统自带的fork三种进程分析. 1.方式一:fork( ...

  2. Python多进程库multiprocessing创建进程以及进程池Pool类的使用

    问题起因最近要将一个文本分割成好几个topic,每个topic设计一个regressor,各regressor是相互独立的,最后汇总所有topic的regressor得到总得预测结果.没错!类似bag ...

  3. 【python小随笔】进程池 multiprocessing.Pool的简单实现与踩过的坑

    #导入进程模块 import multiprocessing #创建进程池 坑:一定要在循环外面创建进程池,不然会一直创建 pool = multiprocessing.Pool(30) for Si ...

  4. Python之路(第三十七篇)并发编程:进程、multiprocess模块、创建进程方式、join()、守护进程

    一.在python程序中的进程操作 之前已经了解了很多进程相关的理论知识,了解进程是什么应该不再困难了,运行中的程序就是一个进程.所有的进程都是通过它的父进程来创建的.因此,运行起来的python程序 ...

  5. python全栈开发 * 进程理论 进程创建 * 180724

    一.进程理论 1.进程是资源分配的最小单位. 2.进程调度就是多个进程在操作系统的控制下被CPU执行,去享用计算机的资源. 先来先服务 短作业优先 时间片轮转 多级反馈队列 3.进程调度的过程是不能够 ...

  6. Python多进程库multiprocessing中进程池Pool类的使用[转]

    from:http://blog.csdn.net/jinping_shi/article/details/52433867 Python多进程库multiprocessing中进程池Pool类的使用 ...

  7. Python: 多进程的分布式进程multiprocessing.managers

    multiprocessing.managers 在Thread和Process中,应当优选Process,因为Process更稳定,而且,Process可以分布到多台机器上,而Thread最多只能分 ...

  8. Python之网路编程利用multiprocessing开进程

    一.multiprocessing模块介绍 python中的多线程无法利用CPU资源,在python中大部分情况使用多进程.python中提供了非常好的多进程包multiprocessing. mul ...

  9. Python创建进程、线程的两种方式

    代码创建进程和线程的两种方式 """ 定心丸:Python创建进程和线程的方式基本都是一致的,包括其中的调用方法等,学会一个 另一个自然也就会了. "" ...

随机推荐

  1. Nginx如何配置静态文件直接访问

    其实前面在这篇文章Nginx之动静分离中已经提到过如何配置静态文件直接访问,今天突然再写是因为之前写的不够完善,所以这一篇文章你可以理解为是在前一个基础上的扩展. 之所以下午临时想到这个,是因为之前搭 ...

  2. 关于vmware workstation10常见问题

    简单的说明:win7和win10的解决办法都是这个,都可以用这个解决. 这是一个共性的问题. 出现这个问题的原因是: a.要么是系统更新没有及时正确的关闭虚拟机导致的; b.没有及时将虚拟机手动关闭再 ...

  3. [转]托管DirectX,从MDX到SlimDX的转换

    开始迁移到托管DirectX SlimDX框架的,例如,MDX应用的帕特里克Murrisa地形的浏览器. 在托管DirectX代码所示,到新的代码,与SlimDX评论的形式. MDX迁移项目中Slim ...

  4. Angular动态表单生成(七)

    动态表单生成之拖拽生成表单(上) 这个功能就比较吊炸天了,之前的六篇,都是ng-dynamic-forms自带的功能,可能很多的说明官方的文档都已经写了,我只是个搬运工,而在这篇文章中,我将化身一个工 ...

  5. 中国气象网 气象数据开放平台 API用法 (Android)

    因为要做个天气应用.须要找个天气的API.上网上搜了下都是那几个,并且基本都过时了.百度有个天气API,只是貌似仅仅能提供当天的.网上提到的中国气象接口的文章,大都用的时旧API,有的被封了,有的永远 ...

  6. DQL-联合查询

    一.含义union:合并.联合,将多次查询结果合并成一个结果二.语法查询语句1union [all]查询语句2union [all]... 三.意义1.将一条比较复杂的查询语句拆分成多条语句2.适用于 ...

  7. 【OC底层】AssociatedObject 关联对象

    如何实现给分类“添加成员变量”? 默认情况下,因为分类底层结构的限制,不能添加成员变量到分类中.但可以通过关联对象来间接实现 关联对象提供了以下API 1> 添加关联对象 void objc_s ...

  8. Tarjan算法初探 (1):Tarjan如何求有向图的强连通分量

    在此大概讲一下初学Tarjan算法的领悟( QwQ) Tarjan算法 是图论的非常经典的算法 可以用来寻找有向图中的强连通分量 与此同时也可以通过寻找图中的强连通分量来进行缩点 首先给出强连通分量的 ...

  9. go语言的结构体指针

    Go 语言结构体 Go 语言中数组可以存储同一类型的数据,但在结构体中我们可以为不同项定义不同的数据类型.   结构体是由一系列具有相同类型或不同类型的数据构成的数据集合.   结构体表示一项记录,比 ...

  10. 2015306 白皎 《网络攻防》Exp4 恶意代码分析

    2015306 白皎 <网络攻防>Exp4 恶意代码分析 netstat [Mac.Linux.Win] sysinteral [MS]:1 2 3 一.系统监控--Windows计划任务 ...