Python并发编程

1 进程的创建与结束

1.1 multiprocess.process模块

  • process模块是一个创建进程的模块,借助这个模块,就可以完成进程的创建。
  • 创建一个子进程
from multiprocessing import Process
import time,os

def func():
    time.sleep(2)
    print("i am 子进程,pid %s" %(os.getpid()))


if __name__ == "__main__":
    p = Process(target=func)
    p.start()
    print("i am 主进程,pid %s" %(os.getpid()))
  • join方法的使用,主线程等待子线程终止
from multiprocessing import Process
import time,os

def func():
    time.sleep(2)
    print("i am 子进程,pid %s" %(os.getpid()))


if __name__ == "__main__":
    p = Process(target=func)
    p.start()
    p.join()
    print("i am 主进程,pid %s" %(os.getpid()))
  •   同时开启多个子进程,并且执行完毕后在主进程
from multiprocessing import Process
import time,os

def func():
    time.sleep(2)
    print("i am 子进程,pid %s" %(os.getpid()))


if __name__ == "__main__":
    p_list=[]
    for i in range(4):
        p = Process(target=func)
        p.start()
        p_list.append(p)
    for p in p_list:
        p.join()
    time.sleep(1)
    print("i am 主进程,pid %s" %(os.getpid()))
  •  进程与子进程数据是隔离的
from multiprocessing import Process
import time,os

n=100
def func(name):
    n=20
    time.sleep(2)
    print("i am 子进程,pid %s,%s,%s" %(os.getpid(),name,n))


if __name__ == "__main__":
    p_list=[]
    for i in range(4):
        p = Process(target=func,args=(i,))
        p.start()
        p_list.append(p)
    for p in p_list:
        p.join()
    time.sleep(1)
    print("i am 主进程,pid %s,%s" %(os.getpid(),n))
  •   守护进程:会随着主进程的结束而结束。主进程创建守护进程

  其一:守护进程会在主进程代码执行结束后就终止

  其二:守护进程内无法再开启子进程,否则抛出异常:AssertionError: daemonic processes are not allowed to have children

注意:进程之间是互相独立的,主进程代码运行结束,守护进程随即终止

from multiprocessing import Process
import time,os

def func(name):
    time.sleep(2)
    print("i am 子进程,pid %s,%s" %(os.getpid(),name))


if __name__ == "__main__":
    p = Process(target=func,args=('abc',))
    p.daemon = True
    p.start()
    print("i am 主进程,pid %s" %(os.getpid()))
  • 主进程代码执行结束守护进程立即结束
from multiprocessing import Process
import time,os

def func1(name):
    time.sleep(1)
    print("i am 子进程,pid %s,%s" %(os.getpid(),name))

def func2(name):
    time.sleep(2)
    print("i am 子进程,pid %s,%s" %(os.getpid(),name))


if __name__ == "__main__":
    p1 = Process(target=func1,args=('func1',))
    p2 = Process(target=func2,args=('func2',))
    p1.daemon = True  #p1不会被打出
    p1.start()
    p2.start()
    print("i am 主进程,pid %s" %(os.getpid()))
  • 进程锁:当多个进程使用同一份数据资源的时候,就会引发数据安全或顺序混乱问题。
  • 虽然使用加锁的形式实现了顺序的执行,但是程序又重新变成串行了,这样确实会浪费了时间,却保证了数据的安全
import os,time
from multiprocessing import Process,Lock

def fun1(i,lock):
    lock.acquire()
    time.sleep(1)
    print("%s,%s" %(os.getpid(),i))
    lock.release()


if __name__ == '__main__':
    lock=Lock()
    for i in range(3):
        p=Process(target=fun1,args=(i,lock))
        p.start()
    print("i am 主进程 %s" %(os.getpid()))
  • 模拟抢票需要用到进程锁
import os,time,json
from multiprocessing import Process,Lock

def rob_ticket(num,lock):
    lock.acquire()
    ticket_dic=json.load(open("db"))
    time.sleep(0.2)
    print("剩余的票数为%s" %ticket_dic["count"])
    if ticket_dic["count"]>0:
        ticket_dic["count"]-=1
        time.sleep(1)   #模拟网络延迟
        json.dump(ticket_dic,open("db","w"))
        print("%s抢票成功" %num)
    lock.release()

if __name__=="__main__":
    lock=Lock()
    for num in range(5):
        p=Process(target=rob_ticket,args=(num,lock))
        p.start()
  • 信号量相当于有多把钥匙和锁
  • 模拟KTV房间人进进出出,房间不是一个
#!/usr/bin/env python
import time
from multiprocessing import Semaphore,Process

def go_ktv(sem,num):
    sem.acquire()
    print("%s现在在ktv唱歌"%num)
    time.sleep(1)
    sem.release()

if __name__ == "__main__":
    sem=Semaphore(3)
    p_l=[]
    for i in range(10):
        p=Process(target=go_ktv,args=(sem,"User%s"%i))
        p.start()
        p_l.append(p)
    for p in p_l:
        p.join()
    print("主进程:没有人在唱歌了")

  

  

  

原文地址:https://www.cnblogs.com/so-cool/p/9177331.html