Python 47多进程02

进程PID相关

from multiprocessing import Process
import os


def P1():
    print("this is a P1")
    print("子进程的PID",os.getpid())
    print("子进程的父进程的PID",os.getppid()) # 父进程的PID
def P2():
    print("this is a P2")
if __name__ == '__main__':
    a1 = Process(target=P1,)
    a2 = Process(target=P2,name='hahaha') # 指定进程名称
    a1.start()
    a2.start()
    print(a1.name) # 进程名称
    print(a2.name)
    print(a1.pid) # 输出进程的PID号码
    print(os.getpid()) # 输出主进程PID

进程其他方法(结束子进程)

import time
from multiprocessing import Process

def P1():
    time.sleep(5)
    print("process 1")

if __name__ == '__main__':
    a1 = Process(target=P1,)
    a1.start()
    print(a1.is_alive()) # 查看子进程是否还在运行
    time.sleep(1)
    a1.terminate() # 给系统一个结束子进程的信号 返回 None
    time.sleep(1)
    print(a1.is_alive())

进程之间的空间隔离

from multiprocessing import Process
import time
num = int(100)
def p1():
    global num # 声明变量,要对函数外部变量进行修改
    num = int(10)
    print("子进程中:",num)

print('>>',num)
if __name__ == '__main__':
    a = Process(target=p1,)
    print("=====01")
    a.start()
    print("=====02")
    a.join() #等待子进程运行结束
    print("=====03")
    print(num)
# 输出的变量值不同 说明进程之间是隔离运行的
主进程中print 执行两次问题

python 每次执行都会加载默认main函数 子进程执行时会把主进程中的所有代码当做main(或模块)加载一遍.所以会有输出两边

守护进程

# 守护进程 一直在后台运行 主进程一旦结束了 所有的子进程都要结束
import time
from multiprocessing import Process

def p1():
    time.sleep(5)
    print("this is a p1")

if __name__ == '__main__':
    a = Process(target=p1,)
    a.daemon = True # 将该进程设置为守护进程 必须写在start 之前 如果主进程结束 那么子进程也要立即结束
    a.start()

print("主进程结束")

主进程结束并不意味这代码的结束,而其中的普通子进程还在运行 ,daemon 只是将其设为守护进程,如果主进程结束,那么守护进程也会结束,但是普通进程还会继续运行.

僵尸进程和孤儿进程

僵尸进程:子进程比父进程先结束,但是父进程又没有回收子进程的资源,子进程成为一个僵尸进程,所以主进程要等待子进程执行结束,回收子进程的资源.
孤儿进程:父进程被杀死了,子进程没有了父进程,所有进程都在init进程下,孤儿进程将直接被init进程接管回收.

锁(互斥锁,进程锁,同步锁)

from multiprocessing import Process,Lock
import json
import time

def p(i,lic):
    # 加锁 当所有进程运行到这里的时候 只有一个能抢到这个锁 其他的执行到此会进行等待
    lic.acquire()
    time.sleep(1)
    print("%s"%i)
    # 解锁 表示当前结束了 其他的可以继续来抢了
    lic.release()

if __name__ == '__main__':
    lic = Lock()
    for i in range(10):
        a = Process(target=p,args=(i,lic))
        a.start()

模拟测试抢票代码

from multiprocessing import Process,Lock
import json
import time

def show_1(i):
    with open ('ticket','r',encoding='utf-8') as f:
        ticket_data = f.read()
    #print(ticket_data)
    #print(eval(ticket_data))
    t_data = eval(ticket_data)
    #print(t_data,type(t_data))
    print('%s查询剩余票数:%s'%(i,t_data['count']))

def get_1(i,l1):
# 加锁
    l1.acquire()
    print("%s开始!"%i)
    with open ('ticket','r',encoding='utf-8') as f:
        ticket_data = f.read()
    t_data = eval(ticket_data)
    if t_data['count'] > 0:
        t_data['count'] -= 1
        print("%s开始抢票"%i)
        time.sleep(0.7)
        with open('ticket','w') as w:
            w.write(str(t_data))
            print("%s抢票成功" % i)
        #json.dump(open('ticket','w'),t_data)
    else:
        print("没票了")
        #解锁
    l1.release()
if __name__ == '__main__':
    l1 = Lock()
    for i in range(10):
        p1 = Process(target=show_1,args=(i,))
        #p2 = Process(target=get_1(),)
        p1.start()
    for i in range(10):
        c1 = Process(target=get_1,args=(i,l1))
        c1.start()

数据共享

进程之前空间是隔离的,但是有些情况需要多个进程配合,所以设计进程通信
from multiprocessing import Process,Manager,Lock
import time
def f1(md,i,l2):
# 执行到此处都会等待 并行程序再次串行话 虽然降低了效率但是保证了安全
    l2.acquire()
    print("%s开始!"%i)
    #md['name'] += 1
    tmp = md['name']
    tmp -= 1
    time.sleep(1)
    md['name'] = int(tmp)
    l2.release()
# for 循环创建子进程 并且等待子进程全部执行结束
if __name__ == '__main__':
    plist = []
    l2 = Lock()
    m = Manager()
    # 创建了一个manager类型的字典 用于进程通信数据共享
    md = m.dict({'name':100})
    for i in range(10):
        p = Process(target=f1,args=(md,i,l2))
        p.start()
        plist.append(p)
    #[k.join for k in plist]
    for k in plist:
        k.join()
    print(md['name'])
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章