---恢复内容开始---

进程

由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在python中大部分情况需要使用多进程。Python提供了非常好用的多进程包multiprocessing,只需要定义一个函数,Python会完成其他所有事情。借助这个包,可以轻松完成从单进程到并发执行的转换。multiprocessing支持子进程、通信和共享数据、执行不同形式的同步,提供了Process、Queue、Pipe、Lock等组件。

  multiprocessing包是Python中的多进程管理包。与threading.Thread类似,它可以利用multiprocessing.Process对象来创建一个进程。该进程可以运行在Python程序内部编写的函数。该Process对象与Thread对象的用法相同,也有start(), run(), join()的方法。此外multiprocessing包中也有Lock/Event/Semaphore/Condition类 (这些对象可以像多线程那样,通过参数传递给各个进程),用以同步进程,其用法与threading包中的同名类一致。所以,multiprocessing的很大一部份与threading使用同一套API,只不过换到了多进程的情境。

创建进程的两种方法

调用内置的方法

from multiprocessing import Process
import time def fun(name):
print(name+' is running')
time.sleep(2)
print(name+' end') if __name__ == '__main__':
pro = Process(target=fun,args=('no1',))
pro.start()

自定义类

from multiprocessing import Process
import os class Myprocess(Process):
def __init__(self,name):
Process.__init__(self)
self.name = name
def run(self):
print(os.getpid())
print(self.name+' is running')
if __name__=='__main__':
p1 = Myprocess('1')
p2=Myprocess('2')
p3=Myprocess('3') p1.start()
p2.start()
p3.start()

注意:在运行的时候要在main里面运行,因为子进程是通过导入模块的方式拿到父进程的代码,如果没有main会一直开启子进程,而子进程的申请是需要开辟内存以及申请pid等的。

进程间通讯

队列queue()

使用方法跟threading里的queue类似,但是不同进程间内存是不共享的,所以要用下面的方法

from multiprocessing import Process, Queue

def f(q,n):
q.put('hello') def f1(q):
print(q.get())
if __name__ == '__main__':
q = Queue()
for i in range(2):
p = Process(target=f, args=(q,i))
p.start()
tp1 = Process(target=f1,args=(q,))
tp2 = Process(target=f1, args=(q,))
tp3 = Process(target=f1, args=(q,))
tp1.start()
tp2.start()

要传入一个公共的queue来保证是同一个队列。

管道Pipes

Pipe()返回两个值(conn1,conn2),作为通讯的两个端。通过设置duplex参数来设置两个端口的功能,如果duplex参数为True(默认值),那么这个管道是全双工模式,也就是说conn1和conn2均可收发。duplex为False,conn1只负责接受消息,conn2只负责发送消息。

from multiprocessing import Process, Pipe

def s(conn):
conn.send('hello, how do you do')
conn.close() def r(conn):
print(conn.recv()) if __name__ == '__main__':
conn1, conn2 = Pipe()
p1 = Process(target=s, args=(conn1,))
p2 = Process(target=r, args=(conn2,))
p1.start()
p2.start()

Managers实现进程之间的数据共享

manager支持 listdictNamespaceLockRLockSemaphoreBoundedSemaphoreConditionEventBarrierQueueValue,Array等类型的共享

from multiprocessing import Process, Manager

def f(d, l,n):
d[n] = '1'
d['2'] = 2
d[0.25] = None
l.append(n)
print(l) if __name__ == '__main__':
with Manager() as manager:
d = manager.dict()
l = manager.list(range(5))
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l,i))
p.start()
p_list.append(p)
for res in p_list:
res.join() print(d)
print(l)

待续

从零开始的Python学习Episode 23——进程的更多相关文章

  1. 从零开始的Python学习Episode 22——多线程

    多线程 线程 线程是操作系统能够进行运算调度的最小单位.它被包含在进程之中,是进程中的实际运作单位.一条线程指的是进程中一个单一顺序的控制流,一个进程中可以并发多个线程,每条线程并行执行不同的任务. ...

  2. 从零开始的Python学习Episode 13——常用模块

    模块 一.time模块 时间戳(timestamp) :时间戳表示的是从1970年1月1日00:00:00开始按秒计算的偏移量. 元组(struct_time)   :struct_time元组共有9 ...

  3. 从零开始的Python学习Episode 21——socket基础

    socket基础 网络通信要素: A:IP地址   (1) 用来标识网络上一台独立的主机 (2) IP地址 = 网络地址 + 主机地址(网络号:用于识别主机所在的网络/网段.主机号:用于识别该网络中的 ...

  4. 从零开始的Python学习Episode 20——面向对象(3)

    面向对象之封装 封装,即隐藏对象的属性和实现细节,仅对外公开接口,控制在程序中属性的读和修改的访问级别:将抽象得到的数据和行为(或功能)相结合,形成一个有机的整体. 隐藏 在python中用双下划线开 ...

  5. 从零开始的Python学习Episode 19——面向对象(2)

    面向对象之继承 继承是一种创建新类的方式,新建的类可以继承一个或多个父类(python支持多继承),父类又可称 为基类或超类,新建的类称为派生类或子类. 子类会“”遗传”父类的属性,从而解决代码重用问 ...

  6. 从零开始的Python学习Episode 17——序列化

    序列化 我们把对象(变量)从内存中变成可存储或传输的过程称之为序列化,在Python中叫pickling,在其他语 言中也被称之为serialization,marshalling,flattenin ...

  7. 从零开始的Python学习Episode 16——模块

    一.模块 在计算机程序的开发过程中,随着程序代码越写越多,在一个文件里代码就会越来越长,越来越不容易维护. 为了编写可维护的代码,我们把很多函数分组,分别放到不同的文件里,这样,每个文件包含的代码就相 ...

  8. 从零开始的Python学习Episode 14——日志操作

    日志操作 一.logging模块 %(message)s 日志信息 %(levelno)s 日志级别 datefmt 设置时间格式 filename 设置日志保存的路径 level 设置日志记录的级别 ...

  9. 从零开始的Python学习Episode 15——正则表达式

    正则表达式 正则表达式(或 RE)是一种小型的.高度专业化的编程语言,(在Python中)它内嵌在Python中,并通过 re 模块实现,所以使用时要导入re模块.正则表达式模式被编译成一系列的字节码 ...

随机推荐

  1. 更改backend

    keras默认的backend是tensorflow,更改成theano方法如下: vim ~/.keras/keras.json { "image_dim_ordering":& ...

  2. Opencv——级联分类器(AdaBoost)

    API说明: cv::CascadeClassifier::detectMultiScale(InputArray image,//输入灰度图像 CV_OUT std::vector<Rect& ...

  3. Spring整合MyBatis(二)Spring整合MyBatis

    摘要: 本文结合<Spring源码深度解析>来分析Spring 5.0.6版本的源代码.若有描述错误之处,欢迎指正. 了解了MyBatis的独立使用过程后,我们再看看它与Spring整合的 ...

  4. Centos7安装elasticsearch、logstash、kibana、elasticsearch head

    环境:Centos7, jdk1.8 安装logstash 1.下载logstash 地址:https://artifacts.elastic.co/downloads/logstash/logsta ...

  5. 给button增加下划线

    如何给button增加下划线简单版   - (void)setUnderLineForButton:(UIButton *)btn withTitle:(NSString *)title{ //利用富 ...

  6. HTML:5meta标签

    <h2>一些常用的移动端的meta属性设置</h2><!DOCTYPE html> <!-- 使用 HTML5 doctype,不区分大小写 --> & ...

  7. Cloudera Manager Server CDH 5.15部署

    安装前准备 主机和系统 Host OS Memory IP bigdata001-dev Cent OS 7.4 x64 32G 192.168.1.1 bigdata002-dev Cent OS ...

  8. Scala-字符串操作

    package com.bigdata object StringO { def main(args: Array[String]): Unit = { val s1 = "Hello&qu ...

  9. SVG动画总结

    SVG可以在内部定义CSS动画样式,包括动画,如下面的格式: <svg> <defs> <style> </style> </defs>&l ...

  10. 使用git管理代码

    上传工程 1.登录github后,点击右上角带有+号的图标,输入仓库名创建仓库(Repository). 2.在项目文件夹下执行以下命令: touch README.md git init 如果工程中 ...