八.多线程与多进程

进程与线程的区别

线程共享内存空间,进程的内存是独立的。

线程可以直接访问进程里数据的片段,多个子进程的数据是相互独立的。

同一个进程的线程直接可以交流,两个进程想通信必须通过一个中间代理来实现。

创建新线程很简单,创建新进程需要对其父进程进行一次克隆

一个线程可以控制和操作同一进程里的其他线程,进程只能操作子进程。

对于主线程修改,有可能影响其他线程的运行。对父进程修改不会影响其他子进程。

 

#多线程示例
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()

 

posted @ 2018-02-23 20:43  鱼汁糊粉  阅读(104)  评论(0编辑  收藏  举报