Python之多线程和多进程
一、多线程
1、顺序执行单个线程,注意要顺序执行的话,需要用join。
1 #coding=utf-8 2 3 from threading import Thread 4 import time 5 6 def my_counter(): 7 i = 0 8 for _ in range(100000000): 9 i = i + 1 10 return True 11 12 def main(): 13 thread_array = {} 14 start_time = time.time() 15 for tid in range(2): 16 t = Thread(target=my_counter) 17 t.start() 18 # join阻塞下个线程,除非当前线程执行完毕 19 t.join() 20 end_time = time.time() 21 print("Total time: {}".format(end_time - start_time)) 22 23 if __name__ == '__main__':
执行结果:
2、同时执行两个并发线程
1 #coding=utf-8 2 3 from threading import Thread 4 import time 5 6 def prn_obj(obj): 7 return '\n'.join(['%s:%s' % item for item in obj.__dict__.items()]) 8 9 def my_counter(): 10 i = 0 11 for _ in range(100000000): 12 i = i + 1 13 return True 14 15 def main(): 16 thread_array = {} 17 start_time = time.time() 18 for tid in range(2): 19 t = Thread(target=my_counter) 20 t.start() 21 thread_array[tid] = t 22 for i in range(2): 23 thread_array[i].join() 24 # print("thread type: {}".format(prn_obj(thread_array[i]))) 25 print("thread type: {}".format(thread_array[i].name)) 26 end_time = time.time() 27 print("Total time: {}".format(end_time - start_time)) 28 29 if __name__ == '__main__': 30 main()
下面是用了打印所有属性的方法,这个方法代码中注释了,可重复利用的代码块
二、多进程
1、multiprocessing
multiprocessing是跨平台版本的多进程模块,它提供了一个Process类来代表一个进程对象,下面是示例嗲吗
import os if __name__=='__main__': print 'Process (%s) start...' % os.getpid() pid = os.fork() print pid if pid==0: print 'I am child process (%s) and my parent is %s.' % (os.getpid(), os.getppid()) else: print 'I (%s) just created a child process (%s).' % (os.getpid(), pid)
这个程序如果用单进程写则需要执行10秒以上的时间,而用多进程则启动10个进程并行执行,只需要用1秒多的时间。
在python中建议使用多进程而不是多线程,因为在python的多线程中有个全局解释器锁,这样在做并发效率会不是很高。
进程和进程直接可以用不同的全局解释器锁,可以提高程序效率。
2、进程间通信Queue
进程和进程之前是独立的,如果需要通信就需要Queue创建的对象来处理
1 from multiprocessing import Process,Queue 2 import time 3 4 def write(q): 5 for i in ['A','B','C','D','E']: 6 print('Put %s to queue' % i) 7 q.put(i) 8 time.sleep(0.5) 9 10 def read(q): 11 while True: 12 v = q.get(True) 13 print('get %s form queue' %v) 14 15 if __name__ == '__main__': 16 q = Queue() 17 pw = Process(target=write,args=(q,)) 18 pr = Process(target=read,args=(q,)) 19 pw.start() 20 pr.start() 21 pr.join() 22 pr.terminate()
3、进程池Pool
1 #coding=utf-8 2 3 from multiprocessing import Pool 4 import time 5 6 def f(x): 7 print x*x 8 time.sleep(2) 9 return x*x 10 11 if __name__ == '__main__': 12 '''定义启动的进程数量''' 13 pool = Pool(processes=5) 14 res_list = [] 15 16 for i in range(10): 17 ''' 18 以异步并行的方式启动进程,如果要同步等待的方式, 19 可以在每次启动进程之后调用res.get()方法 20 也可以使用Pool.appley 21 ''' 22 res = pool.apply_async(f,[i,]) 23 print('--------:',i) 24 res_list.append(res) 25 pool.close() 26 pool.join() 27 for r in res_list: 28 print "result",(r.get(timeout=5))
三、多线程与多进程的对比
在一般情况下多个进程的内存资源是相互独立的,而多线程可以共享同一个进程中的内存资源
1 #coding=utf-8 2 3 from multiprocessing import Process 4 import threading 5 import time 6 lock = threading.Lock() 7 8 def run(info_list,n): 9 lock.acquire() 10 info_list.append(n) 11 lock.release() 12 print('%s' % info_list) 13 14 if __name__ == '__main__': 15 info = [] 16 for i in range(10): 17 # target为子进程执行的函数,args为需要给函数传递的参数 18 p = Process(target=run,args=[info,i]) 19 p.start() 20 p.join() 21 time.sleep(1)#这里为了输出整齐让主进程的执行等一下子进程 22 print('-------------------threading---------------------') 23 for i in xrange(1,10): 24 p = threading.Thread(target=run,args=[info,i]) 25 p.start() 26 p.join()
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
· 周边上新:园子的第一款马克杯温暖上架