--并发编程)
并发编程一、概念1、非并发程序由单个步骤序列构成包含独立子任务的程序执行性能低2、并发1异步2分解子任务、简化流程与逻辑3、进程 process一个程序的执行实例每个进程有自己的地址空间、内存、数据栈及辅助数据4、线程 thread同一个进程内可被并行激活的控制流共享相同上下文空间地址、数据结构特点1) 便于信息共享与通信2) 线程访问顺序差异会导致结果不一致条件racecondition5、Python GIL 全局解释器锁Global Interpreter LockPython代码由虚拟机解释器主循环控制完成主循环同时只能有一个控制线程执行I/O密集型程序建议使用多线程计算密集型程序建议使用多进程二、多线程之threading模块1、.Tread 线程类通过基类去执行importtimeimportthreadingdefworker(sleep_time):print({} worker 函数开始于{}.format(threading.current_thread().name,time.ctime()))time.sleep(sleep_time)print({} worker 函数结束于{}.format(threading.current_thread().name,time.ctime()))if__name____main__:print(主函数开始于{}.format(time.ctime()))threads[]t1threading.Thread(targetworker,args(4,))threads.append(t1)t2threading.Thread(targetworker,args(2,))threads.append(t2)fortinthreads:t.start()fortinthreads:t.join()print(主函数结束于{}.format(time.ctime()))通过派生类去执行importtimeimportthreadingdefworker(sleep_time):print({} worker 函数开始于{}.format(threading.current_thread().name,time.ctime()))time.sleep(sleep_time)print({} worker 函数结束于{}.format(threading.current_thread().name,time.ctime()))classMyThread(threading.Thread):def__init__(self,func,args):threading.Thread.__init__(self)self.funcfunc self.argsargsdefrun(self):self.func(*self.args)if__name____main__:print(主函数开始于{}.format(time.ctime()))threads[]t1MyThread(worker,(4,))threads.append(t1)t2MyThread(worker,(2,))threads.append(t2)fortinthreads:t.start()fortinthreads:t.join()print(主函数结束于{}.format(time.ctime()))三、同步锁.acquire() 获得锁.release() 释放锁with lock: 支持上下文操作importtimeimportthreadingimportrandom eggs[]lockthreading.Lock()defput_eggs(num,lst):# lock.acquire()# for i in range(1, num1):# time.sleep(random.randint(0,2))# lst.append(i)# lock.release()withlock:foriinrange(1,num1):time.sleep(random.randint(0,2))lst.append(i)defmain():threads[]foriinrange(0,3):tthreading.Thread(targetput_eggs,args(5,eggs))threads.append(t)fortinthreads:t.start()fortinthreads:t.join()if__name____main__:main()print(eggs)四、队列queue模块importtimeimportthreadingimportrandomimportqueue qqueue.Queue()defproducer(data_queue):foriinrange(5):time.sleep(0.5)mrandom.randint(1,100)data_queue.put(m)print(f{threading.current_thread().name}往队列中添加了一个元素{m})defconsumer(data_queue):whileTrue:try:mdata_queue.get(timeout2)time.sleep(random.randint(0,2))print(f{threading.current_thread().name}从队列中移除了一个元素{m})exceptqueue.Empty:breakelse:data_queue.task_done()defmain():threads[]pthreading.Thread(targetproducer,args(q,))p.start()time.sleep(3)foriinrange(0,2):tthreading.Thread(targetconsumer,args(q,))threads.append(t)fortinthreads:t.start()fortinthreads:t.join()if__name____main__:main()Thread-1往队列中添加了一个元素47Thread-1往队列中添加了一个元素75Thread-1往队列中添加了一个元素79Thread-1往队列中添加了一个元素5Thread-1往队列中添加了一个元素16Thread-2从队列中移除了一个元素47Thread-2从队列中移除了一个元素79Thread-2从队列中移除了一个元素5Thread-3从队列中移除了一个元素75Thread-2从队列中移除了一个元素16五、多进程之multiprocessing模块用法和threading模块一样但是多进程可以充分利用多核多CPU的计算能力适合计算密集型程序六、concurrent.futures 模块importtimeimportthreadingimportrandomimportqueueimportconcurrent.futures num_poollist(range(1,11))defcount(n):foriinrange(10000000):iireturni*ndefworker(x):rescount(x)print(f数字{x}的计算结果是{res})defseq_execution():start_timetime.clock()foriinnum_pool:worker(i)print(f顺序执行的耗时是{time.clock()-start_time}秒)defthread_execution():start_timetime.clock()withconcurrent.futures.ThreadPoolExecutor(max_workers5)asexecutor:foriinnum_pool:executor.submit(worker,i)print(f多线程执行的耗时是{time.clock()-start_time}秒)defprocess_execution():start_timetime.clock()withconcurrent.futures.ProcessPoolExecutor(max_workers5)asexecutor:foriinnum_pool:executor.submit(worker,i)print(f多进程执行的耗时是{time.clock()-start_time}秒)if__name____main__:# seq_execution()# thread_execution()process_execution()