操作系统进程

Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。
进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。显然,程序是死的(静态的),进程是活的(动态的)。进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身。所有由你启动的进程都是用户进程。
通俗地讲,在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样。但实际上在任何一个时间内有且仅有一个进程占有CPU。

多进程

多进程和多线程的区别
多线程使用的是cpu的一个核,适合io密集型。
多进程使用的是cpu的多个核,适合运算密集型。

Multiprocessing支持子进程,通信,共享数据,执行不同形式的同步,提供了Process,Pipe, Lock等组件。

Process

创建一个Process对象

  1. p = multiprocessing.Process(target=worker_1, args=(2, ))

target = 函数名字
args = 函数需要的参数,以tuple的形式传入
注意: 单个元素的tuple的表现形式(元素,)有一个逗号

multprocessing用到的两个方法
cpu_count()          统计cpu总数
active_children()   获得所有子进程

Process的对象常用方法

is_alive()    判断进程是否存活
run()           启动进程
start()         启动进程,会自动调用run方法,这个常用
join(timeout) 等待进程结束或者直到超时

Process的常用属性

name 进程名字
pid 进程的pid

相关代码示例

  1. import multiprocessing
  2.  
  3. import time
  4.  
  5. def worker(args, interval):
  6. print("start worker {0}".format(args))
  7. time.sleep(interval)
  8. print("end worker {0}".format(args))
  9.  
  10. def main():
  11. print("start main")
  12. p1 = multiprocessing.Process(target=worker, args=(1, 1))
  13. p2 = multiprocessing.Process(target=worker, args=(2, 2))
  14. p3 = multiprocessing.Process(target=worker, args=(3, 3))
  15. p1.start()
  16. p2.start()
  17. p3.start()
  18. print("end main")
  19.  
  20. if __name__ == '__main__':
  21. main()
  22.  
  23. 结果:
  24. start main
  25. end main
  26. start worker 1
  27. start worker 3
  28. start worker 2
  29. end worker 1
  30. end worker 2
  31. end worker 3

p = multiprocessing.Process(target=, args=)
target 指定的是当进程执行时,需要执行的函数
args 是当进程执行时,需要给函数传入的参数
注意: args必须是一个tuple, 特别是当函数需要传入一个参数时 (1,)
p 代表的是一个多进程
p.is_alive() 判断进程是否存活
p.run() 启动进程
p.start() 启动进程,他会自动调用run方法,推荐使用start
p.join(timeout) 等待子进程结束或者到超时时间后再继续往下执行
p.terminate() 强制子进程退出
p.name 进程的名字
p.pid 进程的pid

  1. import multiprocessing
  2.  
  3. import time
  4.  
  5. def worker(args, interval):
  6. print("start worker {0}".format(args))
  7. time.sleep(interval)
  8. print("end worker {0}".format(args))
  9.  
  10. def main():
  11. print("start main")
  12. p1 = multiprocessing.Process(target=worker, args=(1, 1))
  13. p2 = multiprocessing.Process(target=worker, args=(2, 2))
  14. p3 = multiprocessing.Process(target=worker, args=(3, 3))
  15. p1.start()
  16. p1.join(timeout=0.5)
  17. p2.start()
  18. p3.start()
  19. print("the number of CPU is: {0}".format(multiprocessing.cpu_count()))
  20. for p in multiprocessing.active_children():
  21. print("The name of active children is: {0}, pid is: {1} is alive".format(p.name, p.pid))
  22. print("end main")
  23.  
  24. if __name__ == '__main__':
  25. main()
  26.  
  27. 结果:
  28. start main
  29. start worker 1
  30. the number of CPU is: 4
  31. The name of active children is: Process-3, pid is: 9056 is alive
  32. The name of active children is: Process-2, pid is: 5844 is alive
  33. The name of active children is: Process-1, pid is: 8428 is alive
  34. end main
  35. start worker 2
  36. start worker 3
  37. end worker 1
  38. end worker 2
  39. end worker 3

创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。

Lock组件

当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行,肯定是不行的,必须是文件写结束以后,才可以进行读操作。或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就要有一个锁机制进行控制。

当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突。主要用到了lock.acquire() 和lock.release()

  1. import time
  2.  
  3. import multiprocessing
  4.  
  5. def add1(lock, value, number):
  6. with lock:
  7. print("start add1 number= {0}".format(number))
  8. for i in range(1, 5):
  9. number += value
  10. time.sleep(0.3)
  11. print("number = {0}".format(number))
  12.  
  13. def add3(lock, value, number):
  14. lock.acquire()
  15. print("start add3 number= {0}".format(number))
  16. try:
  17. for i in range(1, 5):
  18. number += value
  19. time.sleep(0.3)
  20. print("number = {0}".format(number))
  21. except Exception as e:
  22. raise e
  23. finally:
  24. lock.release()
  25. pass
  26.  
  27. if __name__ == '__main__':
  28. print("start main")
  29. number = 0
  30. lock = multiprocessing.Lock()
  31. p1 = multiprocessing.Process(target=add1, args=(lock, 1, number))
  32. p3 = multiprocessing.Process(target=add3, args=(lock, 3, number))
  33. p1.start()
  34. p3.start()
  35. print("end main")
  36.  
  37. 结果:
  38. start main
  39. end main
  40. start add3 number= 0
  41. number = 3
  42. number = 6
  43. number = 9
  44. number = 12
  45. start add1 number= 0
  46. number = 1
  47. number = 2
  48. number = 3
  49. number = 4

共享内存

python的multiprocessing模块也给我们提供了共享内存的操作。
一般的变量在进程之间是没法进行通讯的,multiprocessing给我们提供了Value和Array模块,他们可以在不通的进程中共同使用,Value 和 Array 都需要设置其中存放值的类型,d 是 double 类型,i 是 int 类型。

  1. import time
  2.  
  3. import multiprocessing
  4.  
  5. from multiprocessing import Value, Array, Manager
  6.  
  7. def add1(value, number):
  8. print("start add1 number= {0}".format(number.value))
  9. for i in range(1, 5):
  10. number.value += value
  11. print("number = {0}".format(number.value))
  12.  
  13. def add3(value, number):
  14. print("start add3 number= {0}".format(number.value))
  15. try:
  16. for i in range(1, 5):
  17. number.value += value
  18. print("number = {0}".format(number.value))
  19. except Exception as e:
  20. raise e
  21.  
  22. if __name__ == '__main__':
  23. print("start main")
  24. number = Value('d', 0)
  25. p1 = multiprocessing.Process(target=add1, args=(1, number))
  26. p3 = multiprocessing.Process(target=add3, args=(3, number))
  27. p1.start()
  28. p3.start()
  29. print("end main")
  30.  
  31. 结果:
  32. start main
  33. end main
  34. start add1 number= 0.0
  35. number = 1.0
  36. number = 2.0
  37. number = 3.0
  38. number = 4.0
  39. start add3 number= 4.0
  40. number = 7.0
  41. number = 10.0
  42. number = 13.0
  43. number = 16.0

python多进程(一)的更多相关文章

  1. Python多进程编程

    转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...

  2. Python多进程(1)——subprocess与Popen()

    Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...

  3. Python多进程使用

    [Python之旅]第六篇(六):Python多进程使用   香飘叶子 2016-05-10 10:57:50 浏览190 评论0 python 多进程 多进程通信 摘要:   关于进程与线程的对比, ...

  4. python多进程断点续传分片下载器

    python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...

  5. Python多进程multiprocessing使用示例

    mutilprocess简介 像线程一样管理进程,这个是mutilprocess的核心,他与threading很是相像,对多核CPU的利用率会比threading好的多. import multipr ...

  6. Python多进程并发(multiprocessing)用法实例详解

    http://www.jb51.net/article/67116.htm 本文实例讲述了Python多进程并发(multiprocessing)用法.分享给大家供大家参考.具体分析如下: 由于Pyt ...

  7. python 多进程开发与多线程开发

    转自: http://tchuairen.blog.51cto.com/3848118/1720965 博文作者参考的博文:  博文1  博文2 我们先来了解什么是进程? 程序并不能单独运行,只有将程 ...

  8. Python多进程----从入门到放弃

    Python多进程 (所有只写如何起多进程跑数据,多进程数据汇总处理不提的都是耍流氓,恩,就这么任性) (1)进程间数据问题,因为多进程是完全copy出的子进程,具有独立的单元,数据存储就是问题了 ( ...

  9. day-4 python多进程编程知识点汇总

    1. python多进程简介 由于Python设计的限制(我说的是咱们常用的CPython).最多只能用满1个CPU核心.Python提供了非常好用的多进程包multiprocessing,他提供了一 ...

  10. python 多进程 logging:ConcurrentLogHandler

    python 多进程 logging:ConcurrentLogHandler python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 Co ...

随机推荐

  1. [转]Using Browser Link in Visual Studio 2013

    本文转自:https://docs.microsoft.com/en-us/aspnet/visual-studio/overview/2013/using-browser-link Browser ...

  2. HTML的map-area的使用

    使用背景 在把设置图转成页面的时候,时常会遇到这种情况:一张小图片上有好多个可以点击的小图标,按常规的处理方法是把这一个一个的小图切出来,然后每个加个a标签进行跳转,但是这样会非常的浪费时间,而且会增 ...

  3. Node.js函数

    Node.js 函数 在JavaScript中,一个函数可以作为另一个函数的参数.我们可以先定义一个函数,然后传递,也可以在传递参数的地方直接定义函数. Node.js中函数的使用与Javascrip ...

  4. spring定时任务(@Scheduled注解)

    (一)在xml里加入task的命名空间 xmlns:task="http://www.springframework.org/schema/task" http://www.spr ...

  5. insert into 语句的三种写法

    insert into 语句的三种写法 方式1. INSERT INTO t1(field1,field2) VALUES (v001,v002);            // 明确只插入一条Valu ...

  6. 2017年10月21日 CSS常用样式&鼠标样式 以及 jQuery鼠标事件& jQuery图片轮播& jQuery图片自动轮播代码

    css代码 背景与前景 background-color:#0000; //背景色,样式表优先级高 background-image:url(路径); //设置背景图片 background-atta ...

  7. HwUI下载地址

    下载地址:HwUI.0.0.1.zip

  8. Implementation:Segment Tree 线段树

    早就听人提起过线段树,今天有题搞不出来,讨论上说要用一下线段树,看了下,本质上是空间划分索引,只不过是一维上面的,如果在二维则是四叉树,三维则是八叉树,如果可以动态调整那么跟R-Tree就很相似了,他 ...

  9. 前端AMD、CMD和commonJs-前端知识

    前端AMD和CMD是在模块化的基础上产生并且得到大幅度的引用的. AMD 即Asynchronous Module Definition(点击链接可以查看AMD面试题),中文名是异步模块定义的意思.它 ...

  10. 文档类型、DOCTYPE切换和浏览器模式

    DTD(文档类型定义)是一种机器可读的规则,它们定义XML或HTML的特定版本中允许有什么.不允许有什么.在解析网页时,浏览器将使用这些规则检查页面的有效性并且采取相应的措施.浏览器通过分析页面的DO ...