Process的几个用法和守护进程

Process的几个用法和守护进程

一、Process的 join用法

话不多说,直接上代码

join 用法一 ,单进程
from multiprocessing import Process
import time

def foo():
    print('子进程 start')
    time.sleep(2)
    print('子进程 end')

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
    # time.sleep(5)
    p.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
    print('主进程')
# join用法二(并发)
from multiprocessing import Process
import time

def foo(x):
    print('子进程 start')
    time.sleep(x)
    print('子进程 end')

if __name__ == '__main__':
    p1 = Process(target=foo,args=(1,))
    p2 = Process(target=foo,args=(2,))
    p3 = Process(target=foo,args=(3,))
    start = time.time()
    p1.start()
    p2.start()
    p3.start()  # 这几个相当于并发
    # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
    # time.sleep(5)
    p1.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
    p2.join()
    p3.join()
    # 总时长:按照最长的时间计算多一点
    end = time.time()
    print(end-start)
    print('主进程')
# join用法三(串行)
from multiprocessing import Process
import time

def foo(x):
    print('子进程 start')
    time.sleep(x)
    print('子进程 end')

if __name__ == '__main__':
    p1 = Process(target=foo,args=(1,))
    p2 = Process(target=foo,args=(2,))
    p3 = Process(target=foo,args=(3,))
    start = time.time()
    p1.start()
    p1.join()  # 在这阻塞住,主进程等待该子进程结束,然后再往下执行,(了解:内部会调用wait())
    p2.start()
    p2.join()
    p3.start()  # 这几个相当于并行
    p3.join()

    # 核心需求就是想让子进程执行完,再执行主进程的print,time有弊端
    # time.sleep(5)
    # 总时长:按照最长的时间计算多一点
    end = time.time()
    print(end-start)
    print('主进程')
# 优化join用法二
from multiprocessing import Process
import time

def foo(x):
    print(f'子进程{x} start')
    time.sleep(x)
    print(f'子进程{x} end')

if __name__ == '__main__':
    start = time.time()
    p_list = []
    for i in range(1,4):
        p = Process(target=foo, args=(i,))
        p.start()
        p_list.append(p)
    for p in p_list:
        p.join()
    end = time.time()
    print(end-start)
    print('主进程')

二、Process的pid和ppid用法

需要先导入os模块

站在当前进程的角度:os.getpid()>>>>获取当前进程的pid

​ os.getppid()>>>>获取当前进程的父进程的pid

​ 子进程对象.pid>>>>获取当前进程的子进程pid

具体看以下代码

from multiprocessing import Process,current_process
import time,os
def task():
    print('子进程 start')
    print('在子进程中查看自己的pid',current_process().pid) # 在子进程查看自己pid方法一
    print('在子进程中查看自己的pid',os.getpid()) # 在子进程查看自己pid方法二
    print('在子进程中查看父进程的pid',os.getppid())
    time.sleep(2)
    print('子进程 end')

if __name__ == '__main__':
    p = Process(target=task)
    p.start()
    print('在主进程查看子进程的pid',p.pid)  # 获取pid,一定要写在start()之后
    print('主进程的pid',os.getpid())
    print('主进程的父进程pid',os.getppid())
    print('主进程')

在主进程查看子进程的pid 1928
主进程的pid 2900
主进程的父进程pid 1008
主进程
子进程 start
在子进程中查看自己的pid 1928
在子进程中查看自己的pid 1928
在子进程中查看父进程的pid 2900
子进程 end

三、Process的name用法

这是用来查看进程名的

from multiprocessing import Process,current_process
import time
def foo():
    print('子进程 start')
    print('>>>>',current_process().name)  # 获取当前进程名
    time.sleep(2)
    print('子进程 end')

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    print(p.name)   

Process-1
子进程 start

Process-1
子进程 end

四、Process的is_alive的用法

用来判断进程是否活着,结果是True或False

from multiprocessing import Process,current_process
import time
def foo():
    print('子进程 start')
    time.sleep(2)
    print('子进程 end')

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    print(p.is_alive())  # 没运行完就活着 True
    time.sleep(5)
    print(p.is_alive())  # 代码运行完了就算死了 False
    print('主进程')

True
子进程 start
子进程 end
False
主进程

五、Process的terminate用法

用来直接把进程终止(死掉)

from multiprocessing import Process,current_process
import time
def foo():
    print('子进程 start')
    time.sleep(50)
    print('子进程 end')

if __name__ == '__main__':
    p = Process(target=foo)
    p.start()
    p.terminate()  # 给操作系统发了一个终止进程的请求
    print(p.is_alive())  # 没运行完就活着 True
    p.join()  # 可以不等50秒,直接执行下面的
    print(p.is_alive())

    print('主进程')

True
False
主进程

六、守护进程

守护进程本质也是一个子进程,主进程的代码执行完毕,守护进程就直接结束

from multiprocessing import Process
import time
def foo():
    print('守护进程 start')
    time.sleep(10)
    print('守护进程 end')

if __name__ == '__main__':
    p = Process(target=foo)
    p.daemon = True  # 把这个子进程定义为了守护进程,只陪伴到打印主进程就结束
    p.start()

    print('主进程')  # 这个执行完,主进程的代码就执行完毕,子进程就直接结束,

主进程

七、抢票小程序


from multiprocessing import Process
import json,time,os
def search():
    time.sleep(1)
    with open('db',mode='rt',encoding='utf-8') as fr:
        res = json.load(fr)
        print(f'还剩{res["count"]}张')

def get():
    with open('db',mode='rt',encoding='utf-8') as fr:
        res = json.load(fr)
    time.sleep(1) # 模拟网络io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db',mode='wt',encoding='utf-8') as fw:
            json.dump(res,fw)
            time.sleep(1.5)  # 模拟网络io
            print(f'进程{os.getpid()}抢票成功')
    else:
        print('票已售罄!!!')

def task():
    search()
    get()

if __name__ == '__main__':
    for i in range(15):
        p = Process(target=task)
        p.start()
        p.join()

# 为了保证数据的安全,要牺牲掉效率

猜你喜欢

转载自www.cnblogs.com/zhuangyl23/p/11515426.html