栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Python

进程理论,miltiprocessing模块相关

Python 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

进程理论,miltiprocessing模块相关

Process(group , target , name , args , kwargs),由该类实例化得到的对象,表示一个子进程中的任务(尚未启动)

强调: 1. 需要使用关键字的方式来指定参数 2. args指定的为传给target函数的位置参数,是一个元组形式,必须有逗号 参数介绍: 1 group参数未使用,值始终为None 2 target表示调用对象,即子进程要执行的任务 3 args表示调用对象的位置参数元组,args=(1,2,'kkk',) 4 kwargs表示调用对象的字典,kwargs={'name':'kkk','age':18} 5 name为子进程的名称

join方法

进程间是相互隔离的

1进程的创建
# encoding=utf-8
# 开进程的方法一:
import time
import random
from multiprocessing import Process


def piao(name):
    print('%s piaoing' % name)
    time.sleep(random.randrange(1, 5))
    print('%s piao end' % name)


if __name__ == '__main__':
    p1 = Process(target=piao, args=('kkk',))  # 必须加,号
    p2 = Process(target=piao, args=('ttt',))
    p3 = Process(target=piao, args=('aaa',))
    p4 = Process(target=piao, args=('bbb',))

    p1.start()
    p2.start()
    p3.start()
    p4.start()
    p1.join()#实现与下面代码的同步
    p2.join()
    p3.join()
    p4.join()
    print('===========主线程===========')

    # 以下代码强制同步,拖慢了程序的运行效率
    for i in range(1,4):
        p=Process(target=piao,args=(f'进程{i}',))
        p.start()
        p.join()
    print('===========主线程===========')

    #修改为:
    list_process=[]
    for i in range(1,4):
        p=Process(target=piao,args=(f'进程{i}',))
        p.start()
        list_process.append(p)
    for p in list_process:
        p.join()
    print('===========主线程===========')



# 开进程的方法二:
import time
import random
from multiprocessing import Process


class Piao(Process):
    def __init__(self, name):
        super().__init__()
        self.name = name

    def run(self):
        print('%s piaoing' % self.name)

        time.sleep(random.randrange(1, 5))
        print('%s piao end' % self.name)


if __name__ == '__main__':
    p1 = Piao('ttt')
    p2 = Piao('aaa')
    p3 = Piao('bbb')
    p4 = Piao('ccc')
    p1.start()  # start会自动调用run
    p2.start()
    p3.start()
    p4.start()
    print('===========主线程===========')
2进程其他方法

进程PID(进程的ID号)的查看:Windows系统:(1)tasklist:查看所有进程        (2)tasklist |findstr PID:查看单个进程

import os
from multiprocessing import current_process

#获取当前进程的ID
os.getpid()
current_process().pid
#获取父进程的ID
os.getppid()

p.terminate()#终止当前代码的运行
print(p.is_alive())#判断当前代码是否存活
3守护进程
#直接在p.start的上方加上下面的代码,就可以将子进程设置为守护进程,在主进程结束之后,守护进程也会结束
p.daemon=True
p.start

互斥锁:牺牲效率,保证数据安全,但是不要轻易使用,只在需要保存数据的时候使用。一般不会涉及到直接写Lock相关的代码,都是利用其他人封装好的代码

#文件db的内容为:{"count":1}
#注意一定要用双引号,不然json无法识别

from multiprocessing import Process,Lock
import time,json,random
def search():
    dic=json.load(open('db'))
    print('33[43m剩余票数%s33[0m' %dic['count'])

def get():
    dic=json.load(open('db'))
    time.sleep(random.random())  # 模拟读数据的网络延迟
    if dic['count'] >0:
        dic['count']-=1
        time.sleep(random.random())  # 模拟写数据的网络延迟
        json.dump(dic,open('db','w'))
        print('33[32m购票成功33[0m')
    else:
        print('33[31m购票失败33[0m')

def task(lock):
    search()
    lock.acquire()  # 将买票这一环节由并发变成了串行,牺牲了运行效率但是保证了数据的安全
    get()
    lock.release()

if __name__ == '__main__':
    lock = Lock()
    for i in range(100):  # 模拟并发100个客户端抢票
        p=Process(target=task,args=(lock,))
        p.start()
4队列:代码实现
from multiprocessing import Queue
q=Queue(3)  # 创建一个最大只能容纳3个数据的队列
"""
常用方法
put ,get ,put_nowait,get_nowait,full,empty
"""
q.put(3)  # 往队列中存放数据
q.put(3)
q.put(3)


q.put(3)  # 如果队列已经满了,程序就会停在这里,等待数据被别人取走,再将数据放入队列。如果队列中的数据一直不被取走,程序就会永远停在这里。
try:
    q.put_nowait(3) # 可以使用put_nowait,如果队列满了不会阻塞,但是会因为队列满了而报错。
except:  # 因此我们可以用一个try语句来处理这个错误。这样程序不会一直阻塞下去,但是会丢掉这个消息。
    print('队列已经满了')
    

# 因此,我们再放入数据之前,可以先看一下队列的状态,如果已经满了,就不继续put了。
print(q.full())  # 判断队列中数据是否已存放满了

print(q.get())  # 从队列中获取数据
print(q.get())
print(q.get())


print(q.get()) # 同put方法一样,如果队列已经空了,那么继续取就会出现阻塞。
try:
    q.get_nowait(3) # 可以使用get_nowait,如果队列满了不会阻塞,但是会因为没取到值而报错。
except: # 因此我们可以用一个try语句来处理这个错误。这样程序不会一直阻塞下去。
    print('队列已经空了')

    
print(q.empty())  # 判断队列中数据是否已经被全部取出

利用队列实现进程间通信(IPC),可以简单的理解为一边进程存数据,另一边进程取数据,从而达到数据交互的目的

import random
from multiprocessing import Process,Queue

def put_q(q):
    q.put(random.randint(1,20))
def read_q(q):
    print(q.get())
if __name__ == '__main__':
    q = Queue(5)
    for i in range(1,6):
        p=Process(target=put_q,args=(q,))
        p.start()
    for i in range(1,7):
        p=Process(target=read_q,args=(q,))
        p.start()
5消费者与生产者模型:平衡存取数据的效率问题
import random
from multiprocessing import Process,JoinableQueue

def producer(q):
    for i in range(10):
        q.put(random.randint(1,20))
def consumer(q):
    while True:
        print(q.get())
        q.task_done()#告诉队列已经取出一个数据并且处理完毕
if __name__ == '__main__':
    q = JoinableQueue(5)
    '''内部有一个计数器,当存入一个数据,计数器加一,当执行一次q.task_done(),计数器减一'''

    p=Process(target=producer,args=(q,))
    p.start()
    p1=Process(target=consumer,args=(q,))
    p1.daemon=True
    p1.start()
    p.join()
    q.join()#等待队列中的数据全部取出,再执行以下的代码

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/1025411.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号