python多进程(一)
操作系统进程
Unix/Linux操作系统提供了一个fork()系统调用,它非常特殊。普通的函数调用,调用一次,返回一次,但是fork()调用一次,返回两次,因为操作系统自动把当前进程(称为父进程)复制了一份(称为子进程),然后,分别在父进程和子进程内返回。子进程永远返回0,而父进程返回子进程的ID。这样做的理由是,一个父进程可以fork出很多子进程,所以,父进程要记下每个子进程的ID,而子进程只需要调用getppid()就可以拿到父进程的ID。
进程是程序在计算机上的一次执行活动。当你运行一个程序,你就启动了一个进程。显然,程序是死的(静态的),进程是活的(动态的)。进程可以分为系统进程和用户进程。凡是用于完成操作系统的各种功能的进程就是系统进程,它们就是处于运行状态下的操作系统本身。所有由你启动的进程都是用户进程。
通俗地讲,在操作系统的管理下,所有正在运行的进程轮流使用CPU,每个进程允许占用CPU的时间非常短(比如10毫秒),这样用户根本感觉不出来CPU是在轮流为多个进程服务,就好象所有的进程都在不间断地运行一样。但实际上在任何一个时间内有且仅有一个进程占有CPU。
多进程
多进程和多线程的区别
多线程使用的是cpu的一个核,适合io密集型。
多进程使用的是cpu的多个核,适合运算密集型。
Multiprocessing支持子进程,通信,共享数据,执行不同形式的同步,提供了Process,Pipe, Lock等组件。
Process
创建一个Process对象
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
相关代码示例
import multiprocessing import time def worker(args, interval):
print("start worker {0}".format(args))
time.sleep(interval)
print("end worker {0}".format(args)) def main():
print("start main")
p1 = multiprocessing.Process(target=worker, args=(1, 1))
p2 = multiprocessing.Process(target=worker, args=(2, 2))
p3 = multiprocessing.Process(target=worker, args=(3, 3))
p1.start()
p2.start()
p3.start()
print("end main") if __name__ == '__main__':
main() 结果:
start main
end main
start worker 1
start worker 3
start worker 2
end worker 1
end worker 2
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
import multiprocessing import time def worker(args, interval):
print("start worker {0}".format(args))
time.sleep(interval)
print("end worker {0}".format(args)) def main():
print("start main")
p1 = multiprocessing.Process(target=worker, args=(1, 1))
p2 = multiprocessing.Process(target=worker, args=(2, 2))
p3 = multiprocessing.Process(target=worker, args=(3, 3))
p1.start()
p1.join(timeout=0.5)
p2.start()
p3.start()
print("the number of CPU is: {0}".format(multiprocessing.cpu_count()))
for p in multiprocessing.active_children():
print("The name of active children is: {0}, pid is: {1} is alive".format(p.name, p.pid))
print("end main") if __name__ == '__main__':
main() 结果:
start main
start worker 1
the number of CPU is: 4
The name of active children is: Process-3, pid is: 9056 is alive
The name of active children is: Process-2, pid is: 5844 is alive
The name of active children is: Process-1, pid is: 8428 is alive
end main
start worker 2
start worker 3
end worker 1
end worker 2
end worker 3
创建子进程时,只需要传入一个执行函数和函数的参数,创建一个Process实例,用start()方法启动,这样创建进程比fork()还要简单。
Lock组件
当我们用多进程来读写文件的时候,如果一个进程是写文件,一个进程是读文件,如果两个文件同时进行,肯定是不行的,必须是文件写结束以后,才可以进行读操作。或者是多个进程在共享一些资源的时候,同时只能有一个进程进行访问,那就要有一个锁机制进行控制。
当多个进程需要访问共享资源的时候,Lock可以用来避免访问的冲突。主要用到了lock.acquire() 和lock.release()
import time import multiprocessing def add1(lock, value, number):
with lock:
print("start add1 number= {0}".format(number))
for i in range(1, 5):
number += value
time.sleep(0.3)
print("number = {0}".format(number)) def add3(lock, value, number):
lock.acquire()
print("start add3 number= {0}".format(number))
try:
for i in range(1, 5):
number += value
time.sleep(0.3)
print("number = {0}".format(number))
except Exception as e:
raise e
finally:
lock.release()
pass if __name__ == '__main__':
print("start main")
number = 0
lock = multiprocessing.Lock()
p1 = multiprocessing.Process(target=add1, args=(lock, 1, number))
p3 = multiprocessing.Process(target=add3, args=(lock, 3, number))
p1.start()
p3.start()
print("end main") 结果:
start main
end main
start add3 number= 0
number = 3
number = 6
number = 9
number = 12
start add1 number= 0
number = 1
number = 2
number = 3
number = 4
共享内存
python的multiprocessing模块也给我们提供了共享内存的操作。
一般的变量在进程之间是没法进行通讯的,multiprocessing给我们提供了Value和Array模块,他们可以在不通的进程中共同使用,Value 和 Array 都需要设置其中存放值的类型,d 是 double 类型,i 是 int 类型。
import time import multiprocessing from multiprocessing import Value, Array, Manager def add1(value, number):
print("start add1 number= {0}".format(number.value))
for i in range(1, 5):
number.value += value
print("number = {0}".format(number.value)) def add3(value, number):
print("start add3 number= {0}".format(number.value))
try:
for i in range(1, 5):
number.value += value
print("number = {0}".format(number.value))
except Exception as e:
raise e if __name__ == '__main__':
print("start main")
number = Value('d', 0)
p1 = multiprocessing.Process(target=add1, args=(1, number))
p3 = multiprocessing.Process(target=add3, args=(3, number))
p1.start()
p3.start()
print("end main") 结果:
start main
end main
start add1 number= 0.0
number = 1.0
number = 2.0
number = 3.0
number = 4.0
start add3 number= 4.0
number = 7.0
number = 10.0
number = 13.0
number = 16.0
python多进程(一)的更多相关文章
- Python多进程编程
转自:Python多进程编程 阅读目录 1. Process 2. Lock 3. Semaphore 4. Event 5. Queue 6. Pipe 7. Pool 序. multiproces ...
- Python多进程(1)——subprocess与Popen()
Python多进程方面涉及的模块主要包括: subprocess:可以在当前程序中执行其他程序或命令: mmap:提供一种基于内存的进程间通信机制: multiprocessing:提供支持多处理器技 ...
- Python多进程使用
[Python之旅]第六篇(六):Python多进程使用 香飘叶子 2016-05-10 10:57:50 浏览190 评论0 python 多进程 多进程通信 摘要: 关于进程与线程的对比, ...
- python多进程断点续传分片下载器
python多进程断点续传分片下载器 标签:python 下载器 多进程 因为爬虫要用到下载器,但是直接用urllib下载很慢,所以找了很久终于找到一个让我欣喜的下载器.他能够断点续传分片下载,极大提 ...
- Python多进程multiprocessing使用示例
mutilprocess简介 像线程一样管理进程,这个是mutilprocess的核心,他与threading很是相像,对多核CPU的利用率会比threading好的多. import multipr ...
- Python多进程并发(multiprocessing)用法实例详解
http://www.jb51.net/article/67116.htm 本文实例讲述了Python多进程并发(multiprocessing)用法.分享给大家供大家参考.具体分析如下: 由于Pyt ...
- python 多进程开发与多线程开发
转自: http://tchuairen.blog.51cto.com/3848118/1720965 博文作者参考的博文: 博文1 博文2 我们先来了解什么是进程? 程序并不能单独运行,只有将程 ...
- Python多进程----从入门到放弃
Python多进程 (所有只写如何起多进程跑数据,多进程数据汇总处理不提的都是耍流氓,恩,就这么任性) (1)进程间数据问题,因为多进程是完全copy出的子进程,具有独立的单元,数据存储就是问题了 ( ...
- day-4 python多进程编程知识点汇总
1. python多进程简介 由于Python设计的限制(我说的是咱们常用的CPython).最多只能用满1个CPU核心.Python提供了非常好用的多进程包multiprocessing,他提供了一 ...
- python 多进程 logging:ConcurrentLogHandler
python 多进程 logging:ConcurrentLogHandler python的logging模块RotatingFileHandler仅仅是线程安全的,如果多进程多线程使用,推荐 Co ...
随机推荐
- [转]How to Import a Text File into SQL Server 2012
Importing a using the OpenRowSet() Function The OPENROWSET bulk row set provider is accessed by call ...
- jsonp跨域简单应用(一)
转载:http://www.cnblogs.com/cyg17173/p/5865364.html ashx+jsonp+document.referrer -- 一年前学的JSONP 跨域,一年 ...
- centos7下更新firefox
下载最新版firefox 1.点击三条线-问号-firefox帮助-安装和更新-linux安装-系统和语言下载 保存到指定目录,比如home下 2.解压 tar xjf firefox-*.tar.b ...
- angualrJs实现图片上传功能
整体逻辑:service提供FileReader函数,directive提供点击事件的绑定和监听,controller用来修改html上的ng-src属性值 1.HTML <input type ...
- 2017年5月22日 HTML基础知识(一)
一.Html 结构 1.1.HTML基本文档格式—<html> 标记 —<html>文档的头部好和主体内容 </html> 根标记 —<head> 文 ...
- 利用:before和:after伪类制作类似微信对话框
今天学到了怎么做一个小三角形,进而结合其他属性把类似微信对话框的图形做出来了. 先做出如下形状: .arrow { width: 30px; height:30px; border-width:20p ...
- ORACLE 导出表结构及备注
https://blog.csdn.net/u013303551/article/details/52354230 SELECT t.table_name, t.colUMN_NAME, ...
- android--Git上克隆项目遇到的坑
直接上图,首先你得有你得GitHub项目地址,如下: 然后打开android studio,选择新建项目时从Git上克隆: 点击clone等待完成,新窗口打开. 打开之后可能.或许.大概.也许会出现下 ...
- 五种常用web服务器jvm参数设置
一.tomcat Tomcat默认可以使用的内存为128MB,在较大型的应用项目中,这点内存是不够的,需要调大.有以下几种方法可以选用:第一种方法:在配置文件中设置Windows下,在文件/bi ...
- display:table-cell实现水平垂直居中
如果查看css手册,会发现display有许多带table字样的可选属性,有table.inline-table.table-row-group.table-row.table-cell等10个之多, ...