进程之multiprocessing模块代码篇

这里再把之前的内容总结和补充一下:

并发和并行:

你在干坏事,来了一个电话,干完坏事再去接电话,说明你既不是并发也不是并行。

你在干坏事,来了一个电话,你接完电话接着干坏事,说明你支持并发

你在干坏事,来了一个电话,你边接电话边干坏事,说明你支持并行

同步和异步:

同步:要想执行下一步 必须等待上一步执行完

异步:想要调用一个函数 只需要通知就行了 不需要等待结果就可以继续执行其他代码

下面简单的来一段代码如何让服务端实现并发的效果

#服务端

import socketfrom multiprocessing import Process     def talk(conn):    conn.send(b‘connected‘)    #只要客户端一链接就发过去去一条信息    ret = conn.recv(1024)    print(ret)if __name__ == ‘__main__‘:    sk = socket.socket()      sk.bind((‘127.0.0.1‘, 8080))    sk.listen()    while True:        conn,addr = sk.accept()        p = Process(target=talk,args=(conn,))    #在参数传过来实例化一个进程        p.start()       #开启进程    conn.close()    sk.close()

#客户端
import socketsk = socket.socket()sk.connect((‘127.0.0.1‘,8080))ret = sk.recv(1024)print(ret)msg = input(‘>>>‘)sk.send(msg.encode(‘utf-8‘))sk.close()上面的代码只要一直执行客户端就能够实现一个服务端N个客户端的并发效果
start  开启一个进程join   用join可以让主进程等待子进程结束

守护进程二话不说上代码
# 守护进程# 守护进程会随着主进程的代码执行结束而结束# 正常的子进程没有执行完的时候主进程要一直等着import timefrom multiprocessing import Processdef func():    print(‘--‘*10)    time.sleep(15)    print(‘--‘*10)def cal_time():      #这个子进程变为了守护进程    while True:        time.sleep(1)        print(‘过去了1秒‘)

if __name__ == ‘__main__‘:    p = Process(target=cal_time)    p.daemon = True     # 一定在开启进程之前设置,此处开启了守护进程    p.start()    p2 = Process(target=func)  # 15s    p2.start()    for i in range(100):    # 10s        time.sleep(0.1)        print(‘*‘*i)    #p2.join()       #一旦开启join,守护进程也会等待子进程,因为主进程在等待子进程

# 守护进程的进程的作用:    # 会随着主进程的代码执行结束而结束,不会等待其他子进程# 守护进程 要在start之前设置# 守护进程中 不能再开启子进程

import timefrom multiprocessing import Processdef func():    print(‘wahaha‘)    time.sleep(5)    print(‘qqxing‘)if __name__ == ‘__main__‘:    p = Process(target=func)    p.start()    print(p.is_alive())      time.sleep(0.1)    p.terminate()        # 关闭进程  异步    print(p.is_alive())      time.sleep(1)    print(p.is_alive())

p.is_alive()   # 是否活着 True代表进程还在 False代表进程不在了p.terminate()  # 结束一个进程,但是这个进程不会立刻被杀死,由操作系统决定什么时候死
 
进程的其他方法
属性pid   查看这个进程 进程idname  查看这个进程的名字

def func():    print(‘wahaha‘)    time.sleep(5)    print(‘qqxing‘)if __name__ == ‘__main__‘:    p = Process(target=func)    p.start()    print(p.name,p.pid)    p.name = ‘哇哈哈哈‘   #修改了name的名字    print(p.name)

class MyProcess(Process):    def run(self):        print(‘wahaha‘,self.name,self.pid)        time.sleep(5)        print(‘qqxing‘,self.name,self.pid)if __name__ == ‘__main__‘:    p = MyProcess()    p.start()    print(p.pid)

进程中的其他方法守护进程 p.daemon = True两个方法 p.is_alive() p.terminate()两个属性 p.pid p.name
                          锁在我们费心费力的实现异步并发,提高cpu的利用率的时候,经常会出现多个进程为了抢占输出资源。锁的存在就是为了梳理这些进程之间的关系
from multiprocessing import Lock   lock = Lock()    lock.acquire()  # 需要锁   拿钥匙lock.acquire()  # 需要锁   连续两次拿钥匙阻塞

lock.release()  # 释放锁  还钥匙

锁 就是在并发编程中 保证数据安全
下面模拟一下春运抢票
import jsonimport timeimport randomfrom multiprocessing import Lockfrom multiprocessing import Processdef search(i):    with open(‘ticket‘) as f:            #打开一个ticket文件,里面存放了{"count": 0}        print(i,json.load(f)[‘count‘])   #load方法接收一个文件句柄,直接将文件中的json字符串转换成数据结构返回def get(i):    with open(‘ticket‘) as f:        ticket_num = json.load(f)[‘count‘]        time.sleep(random.random())    #时间在这里停了大于0且小于1之间的小数        if ticket_num>0:      #如果文件中的count对应的值大于0            with open(‘ticket‘,‘w‘) as f:                json.dump({‘count‘:ticket_num-1},f)  #dump方法接收一个文件句柄,直接将字典转换成json字符串写入文件            print(‘%s买到票了‘%i)      #打印结果并且数量减一        else:            print(‘%s没票了‘%i)def task(i,lock):    search(i)           #查票    lock.acquire()      #拿到一把锁    get(i)              #抢票    lock.release()      #释放锁if __name__ == ‘__main__‘:    lock = Lock()   #实例化一把锁    for i in range(20):   #20个人同时抢票        p = Process(target=task,args=(i,lock))       #实例化一个进程对象        p.start()       #执行这个进程
信号量
import timeimport randomfrom multiprocessing import Semaphorefrom multiprocessing import Processdef sing(i,sem):    sem.acquire()    print(‘%s : 进入 ktv‘%i)    time.sleep(random.randint(1,10))    print(‘%s : 出 ktv‘%i)    sem.release()# 迷你唱吧  20个人,同一时间只能有4个人进去唱歌if __name__ == ‘__main__‘:    sem = Semaphore(4)     #这里限制了一次最多几个进程执行    for i in range(20):        Process(target=sing,args=(i,sem)).start()


事件
所有的阻塞 都是同步recv accept input sleep阻塞多个进程  异步阻塞事件 —— 异步阻塞事件 标志 同时 是所有的进程 都陷入阻塞from multiprocessing import Event   #事件e = Event() # 实例化一个事件  标志/交通信号灯e.set()     # 将标志变成非阻塞/交通灯变绿e.wait()    # 刚实例化出来的一个事件对象,默认的信号是阻塞信号/默认是红灯,执行到wait,要先看灯,绿灯行红灯停,如果在停的过程中灯绿了,就变成非阻塞了e.is_set()是否非阻塞 True就是绿灯 False就是红灯
下面就举例马路上的红绿灯来看一下事件
import timeimport randomfrom multiprocessing import Processfrom multiprocessing import Eventdef traffic_light(e):    while True:        if e.is_set():     #判断是红灯还是绿灯            time.sleep(3)            print(‘红灯亮‘)            e.clear()      # 绿变红        else:            time.sleep(3)            print(‘绿灯亮‘)            e.set()        # 红变绿def car(i,e):    e.wait()    print(‘%s车通过‘%i)if __name__ == ‘__main__‘:    e = Event()   # 立一个红灯    tra = Process(target=traffic_light,args=(e,))    tra.start()   # 启动一个进程来控制红绿灯    for i in range(100):        if i%6 == 0 :            time.sleep(random.randint(1,3))        car_pro = Process(target=car, args=(i,e))        car_pro.start()
通过上述代码可以看出,Event模块的作用就是通过判断是否阻塞然后来改变阻塞状态来实现自己想要的效果

队列

it行业当中总会有一些莫名其妙的需求,这是一种钻研精神。比如,现在某个人有一种想法,能不能实现两个进程之间的通话呢?
from multiprocessing import Queueq = Queue(2)    #这里不传参数就会默认数据长度无限制,现在限制最多只能放两个值,如果放三个值是放不进去的q.put(1)q.put(2)q.put(3)      #put()是放数据,现在放了三个print(q.get())print(q.get())print(q.get())  # get()往外拿值print(q.get())  # 前面一共放了三个值,如果队列里已经没有值了 就会阻塞等待有一个值

1.进程之间通信 可以使用multiprocessing 的 Queue模块2.队列有两种创建方式 第一种不传参数 这个队列就没有长度限制 ;如果传参数,则创建一个有最大长度限制的队列3.提供两个重要方法;put get
 
from multiprocessing import Processfrom multiprocessing import Queueimport randomdef q_put(q):      q.put(‘hello‘)   #往队列里放值def q_get(q):    print(q.get())   #从队列里拿值if __name__ ==‘__main__‘:    q = Queue()    p = Process(target=q_put,args=(q,))    p.start()    p1 = Process(target=q_get, args=(q,))    p1.start()上面代码通过队列实现了,主进程与子进程的通信,子进程与子进程之间的通信

生产者消费者模型我要生产一个数据 然后 给一个函数 让这个函数依赖这个数据进行运算  拿到结果  —— 同步过程下面来一个做包子和吃包子的例子import timedef producer(q):  # 生产者    for i in  range(100):        q.put(‘包子%s‘%i)  #生产者生产包子

def consumer(q): #  消费者    for i in range(100):        time.sleep(1)        print(q.get())   #消费者买包子

if __name__ == ‘__main__‘:    q = Queue(10)   # 生产者做好的包子放在这里,一次放十个    p = Process(target=producer,args=(q,))    p.start()    c1 = Process(target=consumer, args=(q,))    c2 = Process(target=consumer, args=(q,))   #一个人买的太慢,再实例化一个消费者    c1.start()    c2.start()

首先 对于内存空间来说 每次只有很少的数据会在内存中对于生产与消费之间的不平衡来说    增加消费者或者增加生产者来调节效率



原文地址:https://www.cnblogs.com/ddjl/p/8406990.html

时间: 2024-11-01 11:49:36

进程之multiprocessing模块代码篇的相关文章

Python进程之multiprocessing模块

python的multiprocessing模块是跨平台的多进程模块,multiprocessing具有创建子进程,进程间通信,队列,事件,锁等功能,multiprocessing模块包含Process,Queue,Pipe,Lock等多个组件. 1.Process 创建进程的类 Process([group [, target [, name [, args [, kwargs]]]]]) 参数介绍:group参数未使用,值始终为Nonetarget表示调用对象,即子进程要执行的任务args表

Python之路——并行编程之multiprocessing模块

Process 1 import socket 2 import time 3 from multiprocessing import Process 4 5 def talk(conn): 6 if type(conn)==socket.socket(): 7 conn.send(b'connected') 8 msg = conn.recv(1024) 9 print(msg) 10 conn.close() 11 12 13 if __name__ == '__main__': 14 sk

创建多进程之multiprocess包中的process模块

创建多进程之multiprocess包中的process模块 1.process模块是一个创建进程的模块 Process([group [, target [, name [, args [, kwargs]]]]]) 由该类实例化得到的对象,表示一个子进程中任务 强调: 需要使用关键字的方式来指定参数 args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍: group参数未使用,值始终为None target表示调用对象,即子进程要执行的任务 args表示调用对

python全栈开发基础【第二十篇】利用multiprocessing模块开进程

一.multiprocessing模块介绍 python中的多线程无法利用CPU资源(主要指计算密集型任务),在python中大部分情况使用多进程.python中提供了非常好的多进程包multiprocessing. multiprocessing模块用来开启子进程,并在子进程中执行功能(函数),该模块与多线程模块threading的编程接口类似. multiprocessing的功能众多:支持子进程.通信和共享数据.执行不同形式的同步,提供了Process.Queue.Pipe.Lock等组件

Day28:Event对象、队列、multiprocessing模块

一.Event对象 线程的一个关键特性是每个线程都是独立运行且状态不可预测.如果程序中的其他线程需要通过判断某个线程的状态来确定自己下一步的操作,这时线程同步问题就 会变得非常棘手.为了解决这些问题,我们需要使用threading库中的Event对象. 对象包含一个可由线程设置的信号标志,它允许线程等待某些事件的发生.在初始情况下,Event对象中的信号标志被设置为假.如果有线程等待一个Event对象,而这个Event对象的标志为假,那么这个线程将会被一直阻塞直至该标志为真.一个线程如果将一个E

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

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

Linkit 7688 DUO(五) 接上各种Arduino传感器和模块—扩展篇

Linkit 系列博文: 联发科Linkit 7688 (一) 上手及在Mac下搭建OpenWrt交叉编译环境,C语言编译Hello,World 联发科Linkit 7688 (二)GPIO基本操作与C语言编程 联发科Linkit 7688 DUO(三): 通过 Arduino 控制外设和传感器 Linkit 7688 DUO(四): 接上各种Arduino传感器和模块--基础篇 Linkit 7688 DUO(五) 接上各种Arduino传感器和模块-扩展篇 Linkit 7688 DUO(六

python MultiProcessing模块进程间通信的解惑与回顾

这段时间沉迷MultiProcessing模块不能自拔,没办法,python的基础不太熟,因此就是在不断地遇到问题解决问题.之前学习asyncio模块学的一知半解,后来想起MultiProcessing模块更是一知半解,趁着暑假无聊就研究了一下,不得不说,这加深了自己对Python基础的掌握与理解...于是就有了这一系列<python标准库之MultiProcessing库的研究 (1)><python MultiProcessing标准库使用Queue通信的注意要点><py

python 3.x 学习笔记16 (队列queue 以及 multiprocessing模块)

1.队列(queue) 用法: import queue q = queue.Queue() #先进先出模式 q.put(1) #存放数据在q里 作用: 1)解耦    2)提高效率 class queue.Queue(maxsize=0)                        #先入先出class queue.LifoQueue(maxsize=0)                  #后进先出 class queue.PriorityQueue(maxsize=0)