Python多进程的使用

多个进程交替执行

os.getpid() 是 Python 的一个内置函数,它返回当前进程的进程ID。在 Unix 和 Windows 系统中,每个进程都有一个唯一的ID,这个ID是一个整数。在 Python 中,你可以使用 os.getpid() 函数来获取当前进程的ID。

id()函数返回对象的唯一标识符,这个标识符是Python内部使用的,通常是一个大的整数。对于同一个对象,每次调用id()函数都会返回相同的值。

例1:双进程运行同一个方法

import os,time
import multiprocessing

def watch():
    for i in range(3):
        print("watching TV...",os.getpid())
        time.sleep(1)
if __name__=="__main__":
    process1=multiprocessing.Process(target=watch)
    process2=multiprocessing.Process(target=watch)
    process1.start()
    process2.start()
"""
watching TV... 1988
watching TV... 14976
watching TV... 1988
watching TV... 14976
watching TV... 1988
watching TV... 14976
"""

例2:多进程运行不同的方法

import multiprocessing
import os
import time
def watch():
    for i in range(3):
        print(f"watching TV....epoce:{i} {os.getpid()}")
        time.sleep(1)
def eat(food):
    for i in range(3):
        print(f"eat {food}.......epoce:{i} ",os.getpid())
        time.sleep(1)
def drink(beverage):
    for i in range(3):
        print(f"drink {beverage}...epoce:{i} ",os.getpid())
        time.sleep(1)
if __name__=="__main__":
    print("main process",os.getpid())

    watch_pro=multiprocessing.Process(target=watch)
    eat_pro= multiprocessing.Process(target=eat,args=("pork",))
    drink_pro=multiprocessing.Process(target=drink,kwargs={"beverage":"coffee"})

    watch_pro.start()
    drink_pro.start()
    eat_pro.start()
    print("main process stop...")
"""
main process 14360
main process stop...
watching TV....epoce:0 8084
drink coffee...epoce:0  6684
eat pork.......epoce:0  11540
watching TV....epoce:1 8084
drink coffee...epoce:1  6684
eat pork.......epoce:1  11540
watching TV....epoce:2 8084
drink coffee...epoce:2  6684
eat pork.......epoce:2  11540
"""

例3:多进程执行,对象内的方法

import multiprocessing
import os
import time
class Human(object):
    def watch(self):
        for i in range(3):
            print(f"watching TV....epoce:{i} {os.getpid()}")
            time.sleep(1)
    def eat(self,food):
        for i in range(3):
            print(f"eat {food}.......epoce:{i} ",os.getpid())
            time.sleep(1)
    def drink(self,beverage):
        for i in range(3):
            print(f"drink {beverage}...epoce:{i} ",os.getpid())
            time.sleep(1)

if __name__=="__main__":
    jack=Human()
    print("main process",os.getpid())
    watch_pro=multiprocessing.Process(target=jack.watch)
    eat_pro= multiprocessing.Process(target=jack.eat,args=("pork",))
    drink_pro=multiprocessing.Process(target=jack.drink,kwargs={"beverage":"coffee"})
    eat_pro2=multiprocessing.Process(target=jack.eat)

    watch_pro.start()
    drink_pro.start()
    eat_pro.start()
    print("main process stop...")
"""
main process 2272
main process stop...
watching TV....epoce:0 21704
drink coffee...epoce:0  16804
eat pork.......epoce:0  14428
watching TV....epoce:1 21704
drink coffee...epoce:1  16804
eat pork.......epoce:1  14428
watching TV....epoce:2 21704
drink coffee...epoce:2  16804
eat pork.......epoce:2  14428
"""

例4:继承Process创建进程

"""
继承process类创建进程
"""
from multiprocessing import Process
import os
import time
class MyProcess(Process):
    def __init__(self,name):
        super().__init__()
        self.name = name
    def run(self):
        for i in range(3):
            print(f'{self.name}{i} is running...{os.getpid()}')
            time.sleep(1)
if __name__=="__main__":
    p1=MyProcess("love")
    p2=MyProcess("desk")
    p3=MyProcess("vary")

    p1.start()
    p2.start()
    p3.start()

守护进程

进程之间是互相独立的,主进程代码运行结束,守护进程随即终止(主进程和子进程是异步的),当主进程停止,该守护进程不在继续执行.守护进程也是一种子进程.
主进程创建守护进程
  其一:守护进程会在主进程代码执行结束后就终止.(但本质上是在主进程结束之前结束的,主进程需要负责回收资源)
  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

例1

主进程比守护进程先结束,因此,主进程打印结果能输出,而守护进程来不及执行它自己的程序而被迫终止

import time
from multiprocessing import Process


def mydaemon():
    while True:
        print("daemon is alive!")
        time.sleep(1)

if __name__ == '__main__':
    p = Process(target=mydaemon)
    p.daemon = True  # 设为守护进程,必须写在start()方法之前
    p.start()
    print("main process ended.")
"""
运行结果:
main process ended.
"""

例2:

主进程比守护进程晚结束,因此,主进程打印结果能输出,而守护进程也有时间在主进程结束之前,执行守护进程自己的程序

import time
from multiprocessing import Process


def mydaemon():
    while True:
        print("daemon is alive!")
        time.sleep(1)

if __name__ == '__main__':
    p = Process(target=mydaemon)
    p.daemon = True  # 设置当前子进程为守护进程,必须写在start()方法之前
    p.start()
    time.sleep(5)
    print("main process ended.")
"""
运行结果:
daemon is alive!
daemon is alive!
daemon is alive!
daemon is alive!
daemon is alive!
main process ended.
"""

多进程间操作共享的数据

例1:多进程买票

创建warehouse.txt来存储票数

{"amount": 4}
"""
加锁:买票
"""
import json
import time
from multiprocessing import Process,Lock

#多进程同时打开操作同一个文件,就会出现资源冲突导致的报错问题
def get_ticket(username):
    """查询余票"""
    time.sleep(0.01)
    data=json.load(open("warehouse.txt","r"))
    print(f"{username}查询余票:{data['amount']}")

def buy_ticket(username):
    """购买车票"""
    time.sleep(0.01)
    data=json.load(open("warehouse.txt","r"))

    #有票,购买成功
    if data["amount"] > 0:
        data["amount"]-=1
        print(f"{username}成功购买车票!")
    else:
        print(f"{username}购买车票失败!")
    time.sleep(0.01)
    #把票的数据放入仓库
    json.dump(data,open("warehouse.txt","w"))

def task(username,lock):

    get_ticket(username)
    #给需要加锁的代码设置加锁和释放锁操作
    lock.acquire()#加锁
    buy_ticket(username)
    
    lock.release()#解锁

if __name__ == '__main__':
    #在主进程中,创建锁
    lock=Lock()
    for i in range(10):
        # 把锁传递到需要加锁的每个子进程中
        p = Process(target=task, args=(f"user-{i}", lock))
        p.start()
user-1查询余票:4
user-0查询余票:4
user-1成功购买车票!
user-2查询余票:4
user-4查询余票:4
user-3查询余票:3
user-0成功购买车票!
user-5查询余票:3
user-6查询余票:2
user-7查询余票:2
user-2成功购买车票!
user-8查询余票:2
user-9查询余票:2
user-4成功购买车票!
user-3购买车票失败!
user-5购买车票失败!
user-6购买车票失败!
user-7购买车票失败!
user-8购买车票失败!
user-9购买车票失败!

例2:改进的多进程买票

get_ticket(username)
    #给需要加锁的代码设置加锁和释放锁操作
    lock.acquire()#加锁
    buy_ticket(username)
    #假如:buy_ticket()方法中,或者这里发生了运行错误,则运行的进程阻塞不释放锁。
    #这导致其他进程也一直处于等待中,拿不到锁
    lock.release()#解锁
"""
改进的买票
"""
import json
import time
from multiprocessing import Process,Lock


def get_ticket(username):
    """查询余票"""
    time.sleep(0.01)
    data=json.load(open("ticket.txt","r"))
    print(f"{username}查询余票:{data['count']}")

def buy_ticket(username):
    """购买车票"""
    time.sleep(0.01)
    
    data=json.load(open("ticket.txt","r"))

    #有票,购买成功
    if data["count"] > 0:
        data["count"]-=1
        print(f"{username}成功购买车票!")
    else:
        print(f"{username}购买车票失败!")
    time.sleep(0.01)
    #把票的数据放入仓库
    json.dump(data,open("ticket.txt","w"))

def task(username,lock):

    get_ticket(username)
    
    # 采用with lock的方式对程序进行加锁,被加锁的代码发生错误了,也可以自动解锁
    with lock:#__enter__和__exit__
        buy_ticket(username)
    

if __name__ == '__main__':
    #在主进程中,创建锁
    lock=Lock()
    for i in range(10):
        # 把锁传递到需要加锁的每个子进程中
        p = Process(target=task, args=(f"user-{i}", lock))
        p.start()

你可能感兴趣的:(Python学习,python)