Python档案袋( 进程与协程 )

Python的进程和线程是使用的操作系统的原生线程和进程,其是去调用操作系统的相应接口实现

进程:之间不可直接共享数据,是资源的集合,进程必须有一个线程

线程:基于进程,之间可直接共享数据,可执行,只有所有的线程执行完毕程序才会退出

守护线程:生命值依赖于创建它的主线程,主程序亡,不管守护进程执行到何步也必须立即亡

多线程:不适用与CPU操作任务大的(如计算等),较适合于IO操作任务大的(如文件读写等)

进程

简单的进程

在Windows上启动进程必须加入【if __name__=="__main__":】,而在linux上则可随意,进程的使用基本与线程相同

import multiprocessing
import time

def run11():
   print("-----  进程  ----")

# win 进程启动,必须加入这句
if __name__=="__main__":
    #启动进程
   t1=multiprocessing.Process(target=run11,args=())
   t1.start()

进程间传递数据之进程队列:

 1 import multiprocessing
 2
 3 def run11(qqlistx):
 4    print("****** 进入进程 ********")
 5    #设置进程数据
 6    qqlistx.put("11111122")
 7
 8 # win 进程启动,必须加入这句
 9 if __name__=="__main__":
10
11     #进程队列
12     qqlistx = multiprocessing.Queue()
13
14     #启动进程,必须传递进程队列
15     t1=multiprocessing.Process(target=run11,args=(qqlistx,))
16     t1.start()
17
18     print("得到进程数据:", qqlistx.get())

进程间传递数据之管道:

 1 import multiprocessing
 2
 3 def run11(pp1):
 4    print("****** 进入进程 ********")
 5
 6    #发送数据
 7    pp1.send("东小东")
 8    print("收到mian进程发来的数据:",pp1.recv())
 9
10 # win 进程启动,必须加入这句
11 if __name__=="__main__":
12
13     #得到管道
14     # 得到两端,如同socket的服务器和客户端
15     #任意一端都可以进行收发
16     pp1,pp2 = multiprocessing.Pipe()
17
18     #启动进程,传递任意一端
19     t1=multiprocessing.Process(target=run11,args=(pp1,))
20     t1.start()
21
22     #另一端接收数据
23     print("得到进程数据:", pp2.recv())
24     pp2.send("收到数据了东小东")

进程之数据共享:

两个进程进行数据共享,列表或者字典数据共享

 1 import multiprocessing
 2
 3 def run11(vv):
 4    print("****** 进入进程 ********")
 5
 6    vv["dong"]="dongxiaodong"
 7    #vv.append("555") #列表
 8
 9 # win 进程启动,必须加入这句
10 if __name__=="__main__":
11
12     #方法一  -------------:
13     # with multiprocessing.Manager() as mssaagex:
14     #       dictx=mssaagex.dict() #得到字典参数
15     #       #listx=mssaagex.list() #得到列表参数
16     #
17     #       #启动进程,传递字典或者列表
18     #       t1=multiprocessing.Process(target=run11,args=(dictx,))
19     #       t1.start()
20     #
21     #       #等待进程接收
22     #       t1.join()
23     #
24     #       #打印字典数据
25     #       print("得到进程数据:", dictx)
26
27      #方法二  -------------------:
28      dictx=multiprocessing.Manager().dict() #得到字典参数
29      #listx=multiprocessing.Manager().list() #得到列表参数
30
31      #启动进程,传递字典或者列表
32      t2=multiprocessing.Process(target=run11,args=(dictx,))
33      t2.start()
34
35      #等待进程接收
36      t2.join()
37
38      #打印字典数据
39      print("得到进程数据:", dictx)

进程锁:

可以保护屏幕打印等,如多个进程同时向屏幕输出数据时,可以保证屏幕数据来自于一个进程,不会出现数据混乱问题

 1 import multiprocessing
 2
 3 def run11(vv):
 4     vv.acquire() #上锁
 5     print("****** 进入进程 ********")
 6     vv.release()  #解锁
 7
 8
 9 # win 进程启动,必须加入这句
10 if __name__=="__main__":
11
12      lockx=multiprocessing.Lock() #得到进程锁
13
14      t2=multiprocessing.Process(target=run11,args=(lockx,))
15      t2.start()

进程池:

确定进程的同时运行个数,更好的进行进程管理

 1 import multiprocessing
 2 import time
 3
 4 def run11(vv):
 5     time.sleep(1)
 6     print("****** 进入进程 ********",vv)
 7
 8 #回调函数
 9 #在主进程中运行
10 def Cal(arg):
11     print("每个进程的回调函数",arg)
12
13 # win 进程启动,必须加入这句
14 if __name__=="__main__":
15
16      poolx=multiprocessing.Pool(2) #得到进程池,最多同时执行2个进程
17
18      #启动进程
19      for i in range(10):
20          #poolx.apply_async(func=run11,args=(i,)) #并行
21          poolx.apply_async(func=run11,args=(i,),callback=Cal) #并行并加入执行完毕的回调函数
22          #poolx.apply(func=run11,args=(i,)) #串行
23
24      #等待并关闭进程
25      poolx.close()
26      poolx.join()
27      print("-----  完毕  -----")

协程:

单线程实现高并发

安装:pip3 install gevent

手动切换:

import greenlet

def gfunx1():
    print("----gfunx1---")
    g2.switch() #手动切换到 gfunx2 中

def gfunx2():
    print("---gfunx2----")

#声明两个协程
g1=greenlet.greenlet(gfunx1)
g2=greenlet.greenlet(gfunx2)

g1.switch() #手动切换到 gfunx1 中

自动切换:

默认是先运行完gfunx1然后再运行gfunx2,但当遇到IO操作则会自动跳转到另一个协程工作,以此实现在协程中遇到IO就互相切换执行的效果

 1 import gevent
 2
 3 def gfunx1():
 4     print("---- gfunx1 ---")
 5     gevent.sleep(3) #模拟 IO 操作为 3 秒,但使用time.sleep(x)则会进行阻塞
 6     print("**** 三秒io操作结束 ******")
 7
 8 def gfunx2():
 9     print("---- gfunx2 ----")
10
11
12 #开启两个协程
13 gevent.joinall([
14     gevent.spawn(gfunx1),
15     gevent.spawn(gfunx2),
16 ])
自动切换进阶:
将一系列阻塞操作让协程识别为IO操作

 1 import gevent
 2 from gevent import monkey
 3 #将所有的阻塞操作(如:网络,延时,文件等)都视为gevent可捕获的IO阻塞操作
 4 #根据库作者提示:此句最好放在其它库import之前,否则会出现警告
 5 monkey.patch_all()
 6
 7 import requests
 8 import time
 9
10 def gfunx1():
11     print("---- gfunx1 ---")
12     res=requests.get("https://img2018.cnblogs.com/blog/1485202/201811/1485202-20181116215233782-319594948.png")
13     open("ww.jpg","wb").write(res.content) #以二进制写文件
14     print("**** 网络操作结束 ******")
15
16 def gfunx2():
17     print("---- gfunx2 ----")
18     time.sleep(3) #延时操作也已视为IO阻塞
19     print("*** 延时操作结束 3s ***")
20
21 def gfunx3(varx):
22     print("---- gfunx3 ----",varx)
23     time.sleep(1)
24     print("*** 延时操作结束 1s ***")
25
26
27  #开启三个协程
28 gevent.joinall([
29     gevent.spawn(gfunx1),
30     gevent.spawn(gfunx2),
31     gevent.spawn(gfunx3,"33333") #传递参数
32  ])

原文地址:https://www.cnblogs.com/dongxiaodong/p/10495501.html

时间: 2024-10-11 22:13:18

Python档案袋( 进程与协程 )的相关文章

python的进程/线程/协程

1.python的多线程 多线程就是在同一时刻执行多个不同的程序,然而python中的多线程并不能真正的实现并行,这是由于cpython解释器中的GIL(全局解释器锁)捣的鬼,这把锁保证了同一时刻只有一个线程被执行. 多线程的特点: 线程比进程更轻量级,创建一个线程要比创建一个进程快10-100倍. 线程共享全局变量. 由于GIL的原因,当一个线程遇到IO操作时,会切换到另一个线程,所以线程适合IO密集型操作. 在多核cpu系统中,最大限度的利用多核,可以开启多个线程,开销比进程小的多,但是这并

多任务-python实现-进程,协程,线程总结(2.1.16)

目录 1.类比 2.总结 关于作者 @ 1.类比 一个生产玩具的工厂: 一个生产线成为一个进程,一个生产线有多个工人,所以工人为线程 单进程-多线程:一条生产线,多个工人 多进程-多线程:多条生产线,多个工人 协程:工人空闲的时候安排做其他事 2.总结 1.进程是资源分配的单位 2.线程为操作系统调度的单位 3.进程切换需要的资源很大,效率很低 4.线程需要的资源一般,效率一般(不考虑GIL) 5.协程切换的任务资源很小,效率高 6.多进程,多线程根据cpu核数不同可能是并行的,但协程是在一个线

Python之路【第七篇】:线程、进程和协程

Python之路[第七篇]:线程.进程和协程 Python线程 Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 #!/usr/bin/env python # -*- coding:utf-8 -*- import threading import time   def show(arg):     time.sleep(1)     print 'thread'+str(arg)   for i in

Python菜鸟之路:Python基础-线程、进程、协程

上节内容,简单的介绍了线程和进程,并且介绍了Python中的GIL机制.本节详细介绍线程.进程以及协程的概念及实现. 线程 基本使用 方法1: 创建一个threading.Thread对象,在它的初始化函数(__init__)中将可调用对象作为参数传入 import threading import time def worker(): time.sleep(2) print("test") for i in range(5): t = threading.Thread(target=

python运维开发(十)----IO多路复用多线程、进程、协程

内容目录: python作用域 python2.7和python3.5的多继承区别 IO多路复用 多线程.进程.协程 python作用域  python中无块级作用域 if 1 == 1: name = 'jabe' print(name) #可以正常输出jabe #在python中无块级作用域 #在c#或者java中是不能这样使用的,提示name未定义的 python中以函数为作用域 def func(): name = 'jbae' func() print(name) #会提示name为定

Python:线程、进程与协程(1)——概念

最近的业余时间主要放在了学习Python线程.进程和协程里,第一次用python的多线程和多进程是在两个月前,当时只是简单的看了几篇博文然后就跟着用,没有仔细去研究,第一次用的感觉它们其实挺简单的,最近这段时间通过看书, 看Python 中文官方文档等等相关资料,发现并没有想想中的那么简单,很多知识点需要仔细去理解,Python线程.进程和协程应该是Python的高级用法.Python的高级用法有很多,看看Python 中文官方文档就知道了,当然有时间看看这些模块是怎么实现的对自己的提高是很有帮

# 进程/线程/协程 # IO:同步/异步/阻塞/非阻塞 # greenlet gevent # 事件驱动与异步IO # Select\Poll\Epoll异步IO 以及selectors模块 # Python队列/RabbitMQ队列

1 # 进程/线程/协程 2 # IO:同步/异步/阻塞/非阻塞 3 # greenlet gevent 4 # 事件驱动与异步IO 5 # Select\Poll\Epoll异步IO 以及selectors模块 6 # Python队列/RabbitMQ队列 7 8 ############################################################################################## 9 1.什么是进程?进程和程序之间有什么

Python:线程、进程与协程(4)——multiprocessing模块(1)

multiprocessing模块是Python提供的用于多进程开发的包,multiprocessing包提供本地和远程两种并发,通过使用子进程而非线程有效地回避了全局解释器锁. (一)创建进程Process 类 创建进程的类,其源码在multiprocessing包的process.py里,有兴趣的可以对照着源码边理解边学习.它的用法同threading.Thread差不多,从它的类定义上就可以看的出来,如下: class Process(object):     '''     Proces

Python:线程、进程与协程(3)——Queue模块及源码分析

Queue模块是提供队列操作的模块,队列是线程间最常用的交换数据的形式.该模块提供了三种队列: Queue.Queue(maxsize):先进先出,maxsize是队列的大小,其值为非正数时为无线循环队列 Queue.LifoQueue(maxsize):后进先出,相当于栈 Queue.PriorityQueue(maxsize):优先级队列. 其中LifoQueue,PriorityQueue是Queue的子类.三者拥有以下共同的方法: qsize():返回近似的队列大小.为什么要加"近似&q

Python:线程、进程与协程(2)——threading模块(1)

上一篇博文介绍了Python中线程.进程与协程的基本概念,通过这几天的学习总结,下面来讲讲Python的threading模块.首先来看看threading模块有哪些方法和类吧. 主要有: Thread :线程类,这是用的最多的一个类,可以指定线程函数执行或者继承自它都可以实现子线程功能. Timer:与Thread类似,但要等待一段时间后才开始运行,是Thread的子类. Lock :原锁,是一个同步原语,当它锁住时不归某个特定的线程所有,这个可以对全局变量互斥时使用. RLock :可重入锁