多进程
1 开启进程的两种方式
#方式一:
from multiprocessing import Process
import time
def task(name):
print(‘%s is running‘ %name)
time.sleep(5)
print(‘%s is done‘ %name)
if __name__ == ‘__main__‘:
p=Process(target=task,args=(‘alex‘,))
p.start()
print(‘主‘)
#方式二:
from multiprocessing import Process
import time
class MyProcess(Process):
def __init__(self,name):
super(MyProcess,self).__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(‘进程1‘)
p.start() #p.run()
print(‘主‘
2 进程之间是内存空间是隔离的
from multiprocessing import Process
import time
n=100
def task():
global n
time.sleep(5)
n=0
if __name__ == ‘__main__‘:
p=Process(target=task)
p.start()
# time.sleep(5)
print(p.is_alive())
p.join()
print(p.is_alive())
print(‘主‘,n)
3 join方法
# from multiprocessing import Process
# import time
# import os
#
# def task(n):
# print(‘%s is runing‘ %os.getpid())
# time.sleep(n)
# print(‘%s is done‘ %os.getpid())
#
#
# if __name__ == ‘__main__‘:
#
# start_time=time.time()
# p1=Process(target=task,args=(1,))
# p2=Process(target=task,args=(2,))
# p3=Process(target=task,args=(3,))
#
# p_l=[p1,p2,p3]
# # p1.start()
# # p2.start()
# # p3.start()
# for p in p_l:
# p.start()
#
# # p3.join() #3
# # p1.join() #
# # p2.join() #
# for p in p_l:
# p.join()
# stop_time=time.time()
# print(‘主‘,(stop_time-start_time))
# from multiprocessing import Process
# import time
# import os
#
# def task(n):
# print(‘%s is runing‘ %os.getpid())
# time.sleep(n)
# print(‘%s is done‘ %os.getpid())
#
#
# if __name__ == ‘__main__‘:
#
# start_time=time.time()
# p1=Process(target=task,args=(1,))
# p2=Process(target=task,args=(2,))
# p3=Process(target=task,args=(3,))
#
# p_l=[p1,p2,p3]
# # p1.start()
# # p2.start()
# # p3.start()
# for p in p_l:
# p.start()
#
# # p3.join() #3
# # p1.join() #
# # p2.join() #
# for p in p_l:
# p.join()
# stop_time=time.time()
# print(‘主‘,(stop_time-start_time))
from multiprocessing import Process
import time
import os
def task(n):
print(‘%s is runing‘ %os.getpid())
time.sleep(n)
print(‘%s is done‘ %os.getpid())
if __name__ == ‘__main__‘:
start_time=time.time()
p1=Process(target=task,args=(1,))
p2=Process(target=task,args=(2,))
p3=Process(target=task,args=(3,))
p1.start()
p1.join()
p2.start()
p2.join()
p3.start()
p3.join()
stop_time=time.time()
print(‘主‘,(stop_time-start_time))
4 进程对象的其他属性或方法
from multiprocessing import Process
import time
import os
def task(n):
print(‘pid:%s ppid:%s‘ %(os.getpid(),os.getppid()))
time.sleep(n)
if __name__ == ‘__main__‘:
p=Process(target=task,args=(15,),name=‘进程1‘)
p.start()
p.terminate()
# time.sleep(1)
print(p.is_alive())
print(‘主pid:%s ppid:%s‘ %(os.getpid(),os.getppid()))
# print(p.pid)
p.name=‘xxxx‘
print(p.name)
5 守护进程
守护进程:当子进程执行的任务在父进程代码运行完毕后就没有存在的必要了,那
该子进程就应该被设置为守护进程
from multiprocessing import Process
import time
def task(name):
p=Process(target=time.sleep,args=(6,))
p.start()
print(‘%s is running‘ %name)
time.sleep(5)
print(‘%s is done‘ %name)
if __name__ == ‘__main__‘:
p=Process(target=task,args=(‘alex‘,))
p.daemon=True
p.start()
time.sleep(1)
print(‘主‘)
#主进程代码运行完毕,守护进程就会结束
from multiprocessing import Process
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == ‘__main__‘:
p1=Process(target=foo)
p2=Process(target=bar)
p1.daemon=True
p1.start()
p2.start()
print("main-------")
6 互斥锁
from multiprocessing import Process,Lock
import json
import time
import random
import os
def search():
time.sleep(random.randint(1,3))
dic=json.load(open(‘db.txt‘,‘r‘,encoding=‘utf-8‘))
print(‘%s 查看到剩余票数%s‘ %(os.getpid(),dic[‘count‘]))
def get():
dic=json.load(open(‘db.txt‘,‘r‘,encoding=‘utf-8‘))
if dic[‘count‘] > 0:
dic[‘count‘]-=1
time.sleep(random.randint(1,3))
json.dump(dic,open(‘db.txt‘,‘w‘,encoding=‘utf-8‘))
print(‘%s 购票成功‘ %os.getpid())
def task(mutex):
search()
mutex.acquire()
get()
mutex.release()
if __name__ == ‘__main__‘:
mutex=Lock()
for i in range(10):
p=Process(target=task,args=(mutex,))
p.start()
# p.join()
7 消息队列
from multiprocessing import Queue
q=Queue(3)
q.put(‘first‘)
q.put(2)
q.put({‘count‘:3})
# q.put(‘fourth‘,block=False) #q.put_nowait(‘fourth‘)
# q.put(‘fourth‘,block=True,timeout=3)
print(q.get())
print(q.get())
print(q.get())
# print(q.get(block=False)) #q.get_nowait()
print(q.get(block=True,timeout=3))
8 生产者消费者模型
#示例一
from multiprocessing import Process,Queue
import time
import random
def producer(name,food,q):
for i in range(3):
res=‘%s%s‘ %(food,i)
time.sleep(random.randint(1,3))
q.put(res)
print(‘厨师[%s]生产了<%s>‘ %(name,res))
def consumer(name,q):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print(‘吃货[%s]吃了<%s>‘ % (name, res))
if __name__ == ‘__main__‘:
#队列
q=Queue()
#生产者们
p1=Process(target=producer,args=(‘egon1‘,‘泔水‘,q))
p2=Process(target=producer,args=(‘egon2‘,‘骨头‘,q))
#消费者们
c1=Process(target=consumer,args=(‘管廷威‘,q))
c2=Process(target=consumer,args=(‘oldboy‘,q))
c3=Process(target=consumer,args=(‘oldgirl‘,q))
p1.start()
p2.start()
c1.start()
c2.start()
c3.start()
p1.join()
p2.join()
q.put(None)
q.put(None)
q.put(None)
print(‘主‘)
#示例二
from multiprocessing import Process,JoinableQueue
import time
import random
def producer(name,food,q):
for i in range(3):
res=‘%s%s‘ %(food,i)
time.sleep(random.randint(1,3))
q.put(res)
print(‘厨师[%s]生产了<%s>‘ %(name,res))
def consumer(name,q):
while True:
res=q.get()
if res is None:break
time.sleep(random.randint(1,3))
print(‘吃货[%s]吃了<%s>‘ % (name, res))
q.task_done()
if __name__ == ‘__main__‘:
#队列
q=JoinableQueue()
#生产者们
p1=Process(target=producer,args=(‘egon1‘,‘泔水‘,q))
p2=Process(target=producer,args=(‘egon2‘,‘骨头‘,q))
#消费者们
c1=Process(target=consumer,args=(‘管廷威‘,q))
c2=Process(target=consumer,args=(‘oldboy‘,q))
c3=Process(target=consumer,args=(‘oldgirl‘,q))
c1.daemon=True
c2.daemon=True
c3.daemon=True
p1.start()
p2.start()
c1.start()
c2.start()
c3.start()
p1.join()
p2.join()
q.join()
print(‘主‘)
多线程
1 开启线程的两种方式
#示例1
from threading import Thread
import time
import random
def piao(name):
print(‘%s is piaoing‘ %name)
time.sleep(random.randint(1,3))
print(‘%s is piao end‘ %name)
if __name__ == ‘__main__‘:
t1=Thread(target=piao,args=(‘alex‘,))
t1.start()
print(‘主‘)
#示例2
from threading import Thread
import time
import random
class MyThread(Thread):
def __init__(self,name):
super().__init__()
self.name=name
def run(self):
print(‘%s is piaoing‘ %self.name)
time.sleep(random.randint(1,3))
print(‘%s is piao end‘ %self.name)
if __name__ == ‘__main__‘:
t1=MyThread(‘alex‘)
t1.start()
print(‘主‘)
2 进程与线程的区别
#示例1
from threading import Thread
import time
import random
import os
def piao():
print(‘%s is piaoing‘ %os.getpid())
time.sleep(random.randint(1,3))
if __name__ == ‘__main__‘:
t1=Thread(target=piao,)
t2=Thread(target=piao,)
t3=Thread(target=piao,)
t1.start()a
t2.start()
t3.start()
print(‘主‘,os.getpid())
#示例2
from threading import Thread
import time
import random
import os
n=100
def piao():
global n
n=0
if __name__ == ‘__main__‘:
t1=Thread(target=piao,)
t1.start()
t1.join()
print(‘主‘,n)
3 守护线程
#示例1
from threading import Thread
import time
def sayhi(name):
print(‘====>‘)
time.sleep(2)
print(‘%s say hello‘ %name)
if __name__ == ‘__main__‘:
t=Thread(target=sayhi,args=(‘egon‘,))
# t.setDaemon(True)
t.daemon=True
t.start()
print(‘主线程‘)
#示例2
from threading import Thread
import time
def foo():
print(123)
time.sleep(1)
print("end123")
def bar():
print(456)
time.sleep(3)
print("end456")
if __name__ == ‘__main__‘:
t1=Thread(target=foo)
t2=Thread(target=bar)
t1.daemon=True
t1.start()
t2.start()
print("main-------")
4 线程的互斥锁
from threading import Thread,Lock
import time
n=100
def task():
global n
with mutex:
temp=n
time.sleep(0.1)
n=temp-1
if __name__ == ‘__main__‘:
start_time=time.time()
mutex=Lock()
t_l=[]
for i in range(100):
t=Thread(target=task)
t_l.append(t)
t.start()
for t in t_l:
t.join()
stop_time=time.time()
print(‘主‘,n)
print(‘run time is %s‘ %(stop_time-start_time))
5 GIL测试
定义:
In CPython, the global interpreter lock, or GIL, is a mutex that prevents multiple
native threads from executing Python bytecodes at once. This lock is necessary mainly
because CPython’s memory management is not thread-safe. (However, since the GIL
exists, other features have grown to depend on the guarantees that it enforces.)
结论:在Cpython解释器中,同一个进程下开启的多线程,同一时刻只能有一个线程执行,无法利用多核优势
#计算密集型:开多进程
from multiprocessing import Process
from threading import Thread
import os,time
def work():
res=0
for i in range(100000000):
res*=i
if __name__ == ‘__main__‘:
l=[]
start=time.time()
for i in range(4):
# p=Process(target=work) #5.826333284378052
p=Thread(target=work) #run time is 19.91913938522339
l.append(p)
p.start()
for p in l:
p.join()
stop=time.time()
print(‘run time is %s‘ %(stop-start))
#I/O密集型:多线程效率高
from multiprocessing import Process
from threading import Thread
import threading
import os,time
def work():
time.sleep(2)
if __name__ == ‘__main__‘:
l=[]
start=time.time()
for i in range(400):
# p=Process(target=work) # 12.465712785720825
p=Thread(target=work) #2.037116765975952
l.append(p)
p.start()
for p in l:
p.join()
stop=time.time()
print(‘run time is %s‘ %(stop-start))#
from threading import Thread,Lock
import time
n=100
def task():
global n
mutex.acquire()
temp=n
time.sleep(0.1)
n=temp-1
mutex.release()
if __name__ == ‘__main__‘:
mutex=Lock()
for i in range(3):
t=Thread(target=task)
t.start()