2019.09.12学习整理

2019.09.12学习整理

孤儿进程

# 孤儿进程(无害) *
# 一个父进程退出,而它的一个或多个子进程还在运行,那么那些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并由init进程对它们完成状态收集工作。

'''
情况1  无害
父进等着子进程都死,回收僵尸进程。

情况2  无害
父进程死了,子进程活着,都要被init进程接管并且回收。

情况3
父进程一直不死,造成了大量僵尸进程。占用了大量的pid号

Procces的join用法

方式一

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



if __name__ == '__main__':
    p = Process(target=foo)
    p.start() #
    # 核心需求就是
    # time.sleep(5)
    p.join() # 阻塞住主进程再等待子进程结束,然后再往下执行,(了解的是:内部会待用wait())
    print('主')

方式二

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() #
    # 核心需求就是
    # time.sleep(5)
    p3.join() #1s
    p1.join() #1s
    p2.join() #1s
    # 总时长:按照最长的时间计算多一点。
    end = time.time()
    print(end-start) #3s多 or 6s多  ?  正解:3s多
    print('主')

方式三

from multiprocessing import Process
import time
def foo(x):
    print(f'进程{x}  start ')
    time.sleep(x)
    print(f'进程{x}  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() #
    p2.start() #
    p2.join() #
    p3.start() #
    p3.join() #
    # 不如不开,直接穿行调用函数反而快
    # foo(1)
    # foo(2)
    # foo(3)
    # 核心需求就是
    # time.sleep(5)
    # p3.join() #1s
    # p1.join() #1s
    # p2.join() #1s
    # 总时长:按照最长的时间计算多一点。
    end = time.time()
    print(end-start) #3s多 or 6s多  ?  正解:3s多
    print('主')

方式四

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)
    print(p_list)
    for p in p_list:
        p.join()
    end = time.time()
    print(end-start) #3s多 or 6s多  ?  正解:3s多
    print('主')

Process的pid用法

pid号是有限的。
解决方案:
最直接的办法就是杀死父进程 。

from multiprocessing import Process,current_process
import time,os

def task():

    print('子进程 start')
    print('在子进程中查看自己的pid',current_process().pid) # 在子进程中查看自己的pid
    print('在子进程中查看父进程的pid',os.getppid()) #
    time.sleep(200)
    print('子进程 end')

if __name__ == '__main__':

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


'''
# 记住这些就ok了 这个是要掌握的
# 角度 站在当前进程的角度
os.getpid()#获取当前进程的pid
os.getppid() #获取当前进程的父进程的pid
子进程对象.pid #获取当前进程的子进程pid

'''


守护进程

方式一

'''
守护进程
守护--》伴随
本质也是一个子进程
主进程的代码执行完毕守护进程直接结束。但是此时主进程可能没有结束.
'''

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



if __name__ == '__main__':
    p = Process(target=foo)
    p.daemon = True # 把这个子进程定义为了守护进程
    p.start()
    time.sleep(2)
    print('主')

方式二

'''
守护进程
守护--》伴随
本质也是一个子进程
主进程的代码执行完毕守护进程直接结束。
'''

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

def task():
    print('子进程 start')
    time.sleep(5)
    print('子进程 end')


if __name__ == '__main__':
    p = Process(target=foo)
    p2 = Process(target=task)
    p.daemon = True # 把这个子进程定义为了守护进程
    p.start()
    p2.start()
    time.sleep(1)
    print('主')

抢票小程序

from  multiprocessing import Process
import json,time,os

def search():
    time.sleep(1) # 模拟网络io
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        print(f'还剩{res["count"]}')

def get():
    with open('db.txt',mode='rt',encoding='utf-8') as f:
        res = json.load(f)
        # print(f'还剩{res["count"]}')
    time.sleep(1) # 模拟网络io
    if res['count'] > 0:
        res['count'] -= 1
        with open('db.txt',mode='wt',encoding='utf-8') as f:
            json.dump(res,f)
            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()


# 为了保证数据的安全,要牺牲掉效率.
原文地址:https://www.cnblogs.com/zhangmingyong/p/11514822.html