之前实现的数据共享的方式只有两种结构Value和Array。Python中提供了强大的Manager专门用来做数据共享的,Manager是进程间数据共享的高级接口。 Manager()返回的manager对象控制了一个server进程,此进程包含的python对象可以被其他的进程通过proxies来访问。从而达到多进程间数据通信且安全。Manager支持的类型有list, dict, Namespace, Lock, RLock, Semaphore, BoundedSemaphore, Condition, Event, Queue, Value和Array。

下面看一个用于多进程共享dict和list数据:

from multiprocessing importManager, Processdefworker(dt, lt):for i in range(10):

dt[i]= i*i #访问共享数据

lt+= [x for x in range(11, 16)]if __name__ == '__main__':

manager=Manager()

dt=manager.dict()

lt=manager.list()

p= Process(target=worker, args=(dt, lt))

p.start()

p.join(timeout=3)print(dt)print(lt)

结果:

{0: 0,1: 1, 2: 4, 3: 9, 4: 16, 5: 25, 6: 36, 7: 49, 8: 64, 9: 81}

[11, 12, 13, 14, 15]

进程池

当使用Process类管理非常多(几十上百个)的进程时,就会显得比较繁琐,Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程。

importtimeimportmultiprocessingdeffun(msg):print("#########start#### {0}".format(msg))

time.sleep(3)print("#########end###### {0}".format(msg))if __name__ == '__main__':print("start main")

pool= multiprocessing.Pool(processes=3) #在进程池中创建3个进程

for i in range(1, 7):

msg= "hello {0}".format(i)

pool.apply_async(fun, (msg,))#执行时间6s+

#pool.apply(fun, (msg,)) #执行时间 6*3=18s+

pool.close() #在调用join之前,要先调用close,否则会报错,close执行完不会有新的进程加入到pool

pool.join() #join 是等待所有的子进程结束,必须在close之后调用

print("end main")

结果:

start main

start hello1start hello2start hello3end hello1start hello4end hello2start hello5end hello3start hello6end hello4end hello5end hello6end main6.18000006676 #使用pool.apply_async()所花费时间

18.2129998207 #使用pool.apply()所花费时间

pool.apply_async   非阻塞,定义的进程池最大数的同时执行

pool.apply         一个进程结束,释放回进程池,开始下一个进程

从上面的结果中我们可以看到,使用pool.apply_async所花费的时间较少。

多线程

Python中提供了threading模块来对多线程进行操作,线程是应用程序中工作的最小单元,多线程适用于密集型io。

多线程的实现方式有两种:

方法一:将要执行的方法作为参数传给Thread的构造方法(和多进程类似)

t = threading.Thread(target=action, args=(i,))

方法二:从Thread类继承,并重写run()方法。

方法一示例:

importthreadingdefworker(args):print("开始子进程 {0}".format(args))print("结束子进程 {0}".format(args))if __name__ == '__main__':print("start main")

t1= threading.Thread(target=worker, args=(1,)) #和多进程类似

t2 = threading.Thread(target=worker, args=(2,))

t1.start()

t2.start()print("end main")

结果:

start main

开始子进程1结束子进程1开始子进程2end main

结束子进程2

方法二示例:

importthreadingimporttimeclassHello(threading.Thread):

# 对run()方法进行重写def __init__(self, args):

super(Hello, self).__init__()

self.args=argsdefrun(self):print("开始子进程 {0}".format(self.args))

time.sleep(1)print("结束子进程 {0}".format(self.args))if __name__ == '__main__':

a= 1

print("start main")

t1= Hello(1)

t2= Hello(2)

t1.start()

t2.start()print("end main")

结果:

start main

开始子进程1开始子进程2end main

结束子进程2结束子进程1

线程锁

当多线程争夺锁时,允许第一个获得锁的线程进入临街区,并执行代码。所有之后到达的线程将被阻塞,直到第一个线程执行结束,退出临街区,并释放锁。

需要注意,那些阻塞的线程是没有顺序的。

importtimeimportthreadingdefsub():globalcount

lock.acquire()#上锁,第一个线程如果申请到锁,会在执行公共数据的过程中持续阻塞后续线程

#即后续第二个或其他线程依次来了发现已经被上锁,只能等待第一个线程释放锁

#当第一个线程将锁释放,后续的线程会进行争抢

'''线程的公共数据'''temp=countprint("temp is {0}".format(temp))

time.sleep(0.001)

count=temp+1

print("count is {0}".format(count))'''线程的公共数据'''lock.release()#释放锁

time.sleep(2)

count=0

l=[]

lock=threading.Lock()for i in range(100):

t=threading.Thread(target=sub,args=())

t.start()

l.append(t)for t inl:

t.join()print(count)

结果:100

线程池

采用线程池,花费的时间更少。

语法结构示例:

importthreadpooldefThreadFun(arg1,arg2):pass

defmain():

device_list=[object1,object2,object3......,objectn]#需要处理的设备个数

task_pool=threadpool.ThreadPool(8)#8是线程池中线程的个数

request_list=[]#存放任务列表

#首先构造任务列表

for device indevice_list:

request_list.append(threadpool.makeRequests(ThreadFun,[((device, ), {})]))#将每个任务放到线程池中,等待线程池中线程各自读取任务,然后进行处理,使用了map函数,不了解的可以去了解一下。

map(task_pool.putRequest,request_list)#等待所有任务处理完成,则返回,如果没有处理完,则一直阻塞

task_pool.poll()if __name__=="__main__":

main()

pip install threadpool   # 安装threadpool

from threadpool import *   #导入模块

pool = ThreadPool(size) # 定义一个线程池,最多能创建size个线程

requests = makeRequests() # 调用makeRequests创建了要开启多线程的函数,以及函数相关参数和回调函数,其中回调函数可以不写,default是无,也就是说makeRequests只需要2个参数就可以运行;

[pool.putRequest(req) for req in requests] # 将所有要运行多线程的请求扔进线程池

pool.wait() # 等待所有的线程完成工作后退出。

[pool.putRequest(req) for req in requests]等同于:

for req in requests:

pool.putRequest(req)

例子:

importthreadpooldefhello(m, n, o):print("m = {0} n={1} o={2}".format(m, n, o))if __name__ == '__main__':#方法1

lst_vars_1 = ['1', '2', '3'] #需要处理的线程个数

lst_vars_2 = ['4', '5', '6']

func_var=[(lst_vars_1, None), (lst_vars_2, None)]#方法2

#dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'}

#dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'}

#func_var = [(None, dict_vars_1), (None, dict_vars_2)]

pool= threadpool.ThreadPool(2) #线程池中的线程个数

requests = threadpool.makeRequests(hello, func_var) #创建了要开启多线程的函数,创建需要线程池处理的任务,只需要两个参数

[pool.putRequest(req) for req in requests] #将每个任务放入到线程池中

pool.wait()

结果:

m= 1 n=2 o=3m= 4 n=5 o=6

python 多进程 requests_python多进程(二)相关推荐

  1. python学习笔记(二十七)多线程与多进程

    线程是程序里面的最小执行单元. 进程是资源的集合. 线程是包含在一个进程里面,一个进程可以有多个线程,一个进程里面默认有一个主线程.由主线程去启动子线程. 1.多线程 import threading ...

  2. python如何开启多进程_python如何写多进程

    Python中的多进程是通过multiprocessing包来实现的,和多线程的threading.Thread差不多,它可以利用multiprocessing.Process对 象来创建一个进程对象 ...

  3. Python的multiprocessing多进程

    https://www.cnblogs.com/tkqasn/p/5701230.html 由于GIL的存在,python中的多线程其实并不是真正的多线程,如果想要充分地使用多核CPU的资源,在pyt ...

  4. python多线程好还是多协程好_深入浅析python中的多进程、多线程、协程

    进程与线程的历史 我们都知道计算机是由硬件和软件组成的.硬件中的CPU是计算机的核心,它承担计算机的所有任务. 操作系统是运行在硬件之上的软件,是计算机的管理者,它负责资源的管理和分配.任务的调度. ...

  5. Python——多线程与多进程

    Python--多线程与多进程 学习python进阶能力,多进程与多线程的能力是必须的,不然真out了.以下内容部分摘自博客:Python 多线程与多进程.Python:多线程及多进程的使用. 一.线 ...

  6. Python多线程与多进程微信公众号后台开发

    目录 前言 一.线程与进程 1.什么是线程 2.什么是进程 3.进程与线程的关系 4.总结 5.CPU密集型与IO密集型 二.Python的多线程和多进程 1.GIL(Global Interpret ...

  7. python 神经网络 多进程_Pytorch多进程最佳实践

    预备知识 模型并行( model parallelism ):即把模型拆分放到不同的设备进行训练,分布式系统中的不同机器(GPU/CPU等)负责网络模型的不同部分 -- 例如,神经网络模型的不同网络层 ...

  8. python廖雪峰_【Python】python中实现多进程与多线程

    进程与线程 进程(process)就是任务,是计算机系统进行资源分配和调度的基本单位[1].比如,打开一个word文件就是启动了一个word进程. 线程(thread)是进程内的子任务.比如word中 ...

  9. python多进程_python多进程

    上一期我们讲了python中多线程的使用,忘记的小伙伴请戳链接复习,https://zhuanlan.zhihu.com/p/262638052. 还记得我们说到,多线程并不是真正的并发,只是充分利用 ...

最新文章

  1. 拿什么留住你,我的程序员
  2. Cissp-【第3章 安全工程】-2021-2-22(269页-289页)
  3. Scanner类详解
  4. Arthas | 定位线上 Dubbo 线程池满异常
  5. 边锋游戏:用精细化运营使游戏流失率降低 26% ,只是数据驱动价值的冰山一角...
  6. security 底层原理_spring security 实现remeber me(免登陆功能)的原理
  7. java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?
  8. matlab 实现行程编码 对二值图像进行编解码
  9. Python 学习笔记(五)杂项
  10. 2014年第五届蓝桥杯国赛试题(JavaA组)
  11. Ps 初学者教程,如何用文字增强您的照片?
  12. DEV控件之ChartControl用法
  13. 新手引导 自定义遮罩 点击穿透
  14. 指标权重确定方法之熵权法
  15. Web前端开发技术实验与实践(第3版)储久良编著实训3
  16. WatchOS开发教程之六: 表盘功能开发
  17. OpenEmu MAME核心自动更新解决
  18. 入行大数据需要学习哪些编程语言
  19. python数据的存储结构是指_python数据结构
  20. Linux 解压缩Windows下zip和WinRAR的分卷文件(奇怪的知识点)

热门文章

  1. JetBrains 第二轮:再为免费全家桶续命三个月
  2. 2019新面貌:博客改版计划进行中!
  3. 重磅!Github 开放无数量限制的免费私有仓库!
  4. Spring Cloud Contract 契约测试实践
  5. 提高语音识别成功率的解决方案思路一
  6. EfficientNetv2测试
  7. pycharm自定义格式化
  8. onnx:Resize in opset 11 to support Pytorch‘s behavior
  9. opencv检测黑色区域
  10. linux opencv