一、共享内存-Manager
Python中提供了强大的Manager专门用来做数据共享的,其支持的类型非常多,包括,Value, Array,list,dict, Queue, Lock等。
示例
from multiprocessing import Manager, Process
def worker(dt, lt):
for i in range(10):
key = "args" + str(i)
dt[key] = i * i
lt += [x for x in range(10)]
if __name__ == '__main__':
# 创建共享内存manager
manager = Manager()
dt = manager.dict()
lt = manager.list()
p = Process(target=worker, args=(dt, lt))
p.start()
p.join()
print(dt)
print(lt)
结果
二、进程池
Pool可以提供指定数量的进程,供用户调用,当有新的请求提交到pool中时,如果池还没有满,那么就会创建一个新的进程用来执行该请求;但如果池中的进程数已经达到规定最大值,那么该请求就会等待,直到池中有进程结束,才会创建新的进程。
进程池有个异步和同步
示例
import time
import multiprocessing
def fun(msg):
print("#############start func############# {0}".format(msg))
time.sleep(3)
print("#############end func############# {0}".format(msg))
if __name__ == '__main__':
print("start main")
pool=multiprocessing.Pool(processes=3) #processes=3定义进程池中最大的进程数据为3个
for i in range(1,7):
msg="hello {0}".format(i)
pool.apply_async(fun,(msg,))
# pool.apply(fun,(msg,))
pool.close()
pool.join()
print("end main")
注:调用join之前,先调用close函数,否则会出错。执行完close后不会有新的进程加入到pool,join函数等待所有子进程结束
阻塞和非阻塞的区别:
Pool.apply_async : 非阻塞,定义的进程池进程最大数可以同时执行。如上面的示例中,进程池晴定义了最大3个进程数(processes=3)
Pool.apply: 一个进程结束,释放回进程池,下一个进程才可以开始
三、多线程
线程是应用程序中工作的最小单元,Python中提供了threading模块来对多线程的操作。
多线程使用的是cpu的一个核,适合io密集型。
3.1多线程是实现方法
多线程是实现有两种方式:
方法一:将要执行的方法作为参数传给Thread的构造方法(和多进程类似)
t = threading.Thread(target=action, args=(i,))
示例
import threading
def worker(args):
print("开始子进程 {0}".format(args))
print("结束子进程 {0}".format(args))
if __name__ == '__main__':
print("start main")
t1=threading.Thread(target=worker,args=(1,))
t2=threading.Thread(target=worker,args=(2,))
t1.start()
t2.start()
print("end main")
方法二:从Thread继承,并重写run()
推荐使用第二种方法
示例
import threading
import time
class Hello(threading.Thread):
def __init__(self, args):
super(Hello, self).__init__()
self.args = args
global a
print("a = {0}".format(a))
a +=1
def run(self):
print("开始子进程 {0}".format(self.args))
time.sleep(1)
print("结束子进程 {0}".format(self.args))
if __name__ == '__main__':
a = 1
print("start main")
t1 = Hello(1)
t2 = Hello(2)
t1.start()
t2.start()
print("#####a = {0}".format(a))
print("end main")
3.2多线程锁
通过threading.Lock()来创建锁,函数在执行的只有先要获得锁,左后执行完以后要释放锁:
import threading
lock=threading.Lock()
lock.acquire() #获取锁
lock.release() #释放锁
#with lock: 跟with.open打开文件的方法一亲
3.3线程池
安装:pip install threadpool
import threadpool from threadpool import * pool=ThreadPool(3) #ThreadPool(size),size表示线程数量有多少 request=makeRequests() def Hello(m,n,o): print("m={0} n={1} o={2}".format(m,n,o)) if __name__ == '__main__': # 方法1 lst_vars_1 = ['1', '2', '3'] lst_vars_2 = ['4', '5', '6'] func_var = [(lst_vars_1, None), (lst_vars_2, None)] # 方法2 # dict_vars_1 = {'m': '1', 'n': '2', 'o': '3'} # dict_vars_2 = {'m': '4', 'n': '5', 'o': '6'} # func_var = [(None, dict_vars_1), (None, dict_vars_2)] pool = threadpool.ThreadPool(2) requests = threadpool.makeRequests(Hello, func_var) [pool.putRequest(req) for req in requests] pool.wait()