八.多线程与多进程
进程与线程的区别
线程共享内存空间,进程的内存是独立的。
线程可以直接访问进程里数据的片段,多个子进程的数据是相互独立的。
同一个进程的线程直接可以交流,两个进程想通信必须通过一个中间代理来实现。
创建新线程很简单,创建新进程需要对其父进程进行一次克隆
一个线程可以控制和操作同一进程里的其他线程,进程只能操作子进程。
对于主线程修改,有可能影响其他线程的运行。对父进程修改不会影响其他子进程。
#多线程示例 import threading def run(n): print("task",n) t1=threading.Thread(target=run,args=("t1",)) t2=threading.Thread(target=run,args=("t2",)) t1.start() t2.start()
queue队列
作用:
1.解耦,使程序之间实现松耦合,修改模块不会影响其他模块
2.提高处理效率
queue与list区别:
queue拿取数据,数据取走就没了,list拿取数据,数据还在list。
q=queue.Queue()#先入先出 q.put()#放数据 q.get()#取数据 q.queue.LifoQueue()#后进先出
import queue q=queue.PriorityQueue()#存储数据时可以设置优先级 q.put((2,"b")) q.put((3,"c")) q.put((1,"a")) #输出结果 (1, 'a') (2, 'b') (3, 'c')
#生产者消费者模型
import queue
import threading
import time
q=queue.Queue()
def Producer(name):
count = 1
while True:
q.put("商品%s" % count)
print("%s生产了商品"%name,count)
count += 1
time.sleep(0.5)
def Consumer(name):
while True:
print("%s买到商品%s" %(name, q.get()))
time.sleep(1)
p=threading.Thread(target=Producer,args=("生产者",))
c1=threading.Thread(target=Consumer,args=("买家1",))
c2=threading.Thread(target=Consumer,args=("买家2",))
p.start()
c1.start()
c2.start()
多进程
import multiprocessing
import time
def run(name):
time.sleep(2)
print('hello',name)
if __name__ == '__main__':
for i in range(10):
p = multiprocessing.Process(target=run,args=('man %s'%i,))
p.start()
进程间通讯
Queue
from multiprocessing import Process,Queue
import threading
def f(q):
q.put([123,'abc'])
if __name__ == '__main__':
q = Queue()
p = Process(target=f, args=(q,))
p.start()
print(q.get())
Pipe
from multiprocessing import Process,Pipe
def a(message):
message.send([123,"fghr"])
message.close
if __name__ == "__main__":
pointa,pointb=Pipe()
p=Process(target=a,args=(pointa,))
p.start()
print(pointb.recv())
manage
以代理的方式在进程间共享字典或列表形式的数据
from multiprocessing import Process, Manager
import os
def f(d, l):
d[os.getpid()] =os.getpid()
l.append(os.getpid())
print(l)
if __name__ == '__main__':
with Manager() as manager:
d = manager.dict() #{} #生成一个字典,可在多个进程间共享和传递
l = manager.list(range(5))#生成一个列表,可在多个进程间共享和传递
p_list = []
for i in range(10):
p = Process(target=f, args=(d, l))
p.start()
p_list.append(p)
for res in p_list: #等待结果
res.join()
print(d)
print(l)
进程池
进程池内部维护一个进程序列,当使用时,则去进程池中获取一个进程,如果进程池序列中没有可供使用的进进程,那么程序就会等待,直到进程池中有可用进程为止。
from multiprocessing import Process, Pool
import time
import os
def Foo(i):
time.sleep(2)
print("in process",os.getpid())
return i + 100
def Bar(arg):
print('-->exec done:', arg,os.getpid())
if __name__ == '__main__':
pool = Pool(processes=3) #允许进程池同时放入5个进程
print("主进程",os.getpid())
for i in range(10):
pool.apply_async(func=Foo, args=(i,), callback=Bar) #callback=回调
#pool.apply(func=Foo, args=(i,)) #串行
#pool.apply_async(func=Foo, args=(i,)) #并行
print('end')
pool.close()#这里join一定是在close之后,且必须要加join,否则主进程不等待创建的子进程执行完毕
pool.join() #进程池中进程执行完毕后再关闭,如果注释,那么程序直接关闭。.join()