开启进程的两种方式

from multiprocessing import Process
import  time

def task(name):
    print('%s is running'%name)
    time.sleep(3)
    print('%s is done' %name)


#在windows系统上,开启子进程的操作必须放到if __name__ =='main'的子代码块中
if __name__ == '__main__':
    p=Process(target=task,args=('egon',))
    p.start()#只是向操作系统发送一个开启子进程的序号
    print('')
方式一
from multiprocessing import Process
import time


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

    def run(self):
        print('%s is running' %self.name)
        time.sleep(3)
        print('%s is done' %self.name)

if __name__ == '__main__':
    p=Myprocess('egon')
    p.start()
    print('')
方式二

 

join:让主进程在原地等待,等待子进程运行完毕,不会影响子进程的执行

 

from multiprocessing import Process
import time


def task(name,n):
    print('%s is running'%name)
    time.sleep(n)
    print('%s is done' %name)

if __name__ == '__main__':
    start=time.time()
    p_l=[]
    for i in range(1,4):
        p=Process(target=task,args=('子%s' %i,i))
        p_l.append(p)
        p.start()

    for p in p_l:
        p.join()
    print('',(time.time()-start))
View Code

 

 

 

守护进程:本质就是一个子进程,该子进程的生命周期<=被守护进程的生命周期

 

from multiprocessing import  Process
import time


def task(name):
    print('%s is run ning' %name)
    time.sleep(3)
    print('%s is done' %name)

if __name__ == '__main__':
    p=Process(target=task,args=('lqx',))
    p.daemon = True
    p.start()
    time.sleep(4)

    print('%s is done' %('egon'))

 

 

 

 

 

进程对象其他相关属性或方法

 

1 group参数未使用,值始终为None
2 
3 target表示调用对象,即子进程要执行的任务
4 
5 args表示调用对象的位置参数元组,args=(1,2,'egon',)
6 
7 kwargs表示调用对象的字典,kwargs={'name':'egon','age':18}
8 
9 name为子进程的名称
参数介绍

 

 1 p.start():启动进程,并调用该子进程中的p.run() 
 2 p.run():进程启动时运行的方法,正是它去调用target指定的函数,我们自定义类的类中一定要实现该方法  
 3 
 4 p.terminate():强制终止进程p,不会进行任何清理操作,如果p创建了子进程,该子进程就成了僵尸进程,使用该方法需要特别小心这种情况。如果p还保存了一个锁那么也将不会被释放,进而导致死锁
 5 p.is_alive():如果p仍然运行,返回True
 6 
 7 p.join([timeout]):主线程等待p终止(强调:是主线程处于等的状态,而p是处于运行的状态)。timeout是可选的超时时间,需要强调的是,p.join只能join住start开启的进程,而不能join住run开启的进程  
方法介绍
1 p.daemon:默认值为False,如果设为True,代表p为后台运行的守护进程,当p的父进程终止时,p也随之终止,并且设定为True后,p不能创建自己的新进程,必须在p.start()之前设置
2 
3 p.name:进程的名称
4 
5 p.pid:进程的pid
6 
7 p.exitcode:进程在运行时为None、如果为–N,表示被信号N结束(了解即可)
8 
9 p.authkey:进程的身份验证键,默认是由os.urandom()随机生成的32字符的字符串。这个键的用途是为涉及网络连接的底层进程间通信提供安全性,这类连接只有在具有相同的身份验证键时才能成功(了解即可)
属性介绍

 

 

 

互斥锁

  进程之间数据不共享,但是共享同一套文件系统,所以访问同一个文件,或同一个打印终端,是没有问题的,而共享带来的是竞争,竞争带来的结果就是错乱,如何控制,就是加锁处理

 

#加锁可以保证多个进程修改同一块数据时,同一时间只能有一个任务可以进行修改,即串行的修改,没错,速度是慢了,但牺牲了速度却保证了数据安全。
虽然可以用文件共享数据实现进程间通信,但问题是:
1.效率低(共享数据基于文件,而文件是硬盘上的数据)
2.需要自己加锁处理
import json
import time,random
from multiprocessing import Process,Lock

def search(name):
    with open('db.json','rt',encoding='utf-8')as f:
        dic=json.load(f)
    time.sleep(1)
    print('%s 查看到余票为%s'%(name,dic['count']))

def get(name):
    with open('db.json','rt',encoding='utf-8')as f:
        dic=json.load(f)
    if dic['count']>0:
        dic['count']-=1
        time.sleep(random.randint(1,3))
        with open('db.json','wt',encoding='utf-8')as f:
            json.dump(dic,f)
            print('%s购票成功'%name)
    else:
        print('%s 查看到没有票了'%name)

def task(name,mutex):
    search(name)
    mutex.acquire()
    get(name)
    mutex.release()

if __name__ == '__main__':
    mutex=Lock()
    for i in range(10):
        p=Process(target=task,args=('路人%s'%i,mutex))
        p.start()
模拟抢票