潍坊建设网站的公司重庆制作网站培训
- 作者: 五速梦信息网
- 时间: 2026年04月20日 07:17
当前位置: 首页 > news >正文
潍坊建设网站的公司,重庆制作网站培训,最新网上注册公司流程,企业网站设计价格本文是一篇学习笔记#xff0c;学习内容主要来源于莫凡python的文档#xff1a;https://mofanpy.com/tutorials/python-basic/threading/thread 多线程
线程基本结构
开启子线程的简单方式如下#xff1a;
import threadingdef thread_job():print(This is a thread of %… 本文是一篇学习笔记学习内容主要来源于莫凡python的文档https://mofanpy.com/tutorials/python-basic/threading/thread 多线程
线程基本结构
开启子线程的简单方式如下
import threadingdef thread_job():print(This is a thread of %s % threading.current_thread())def main():thread threading.Thread(targetthread_job, ) # 定义线程thread.start() # 让线程开始工作if name main:main()线程阻塞
下面是一个双线程的示例期望效果是先运行完两个子线程再输出all done。
import threading
import timedef T1_job():print(T1 start\n)for i in range(10):time.sleep(0.1)print(T1 finish\n)def T2_job():print(T2 start\n)print(T2 finish\n)if name main:thread_1 threading.Thread(targetT1_job, nameT1)thread_2 threading.Thread(targetT2_job, nameT2)thread_1.start() # 开启T1thread_2.start() # 开启T2print(all done\n)输出 T1 start T2 start all done T2 finish T1 finish 实际结果发现主线程没有“等待”子线程执行完就已经结束。 为了达到预期效果需要通过join()方法来设定线程阻塞。
下面再开启T2之前插入thread_1.join()
if name main:thread_1 threading.Thread(targetT1_job, nameT1)thread_2 threading.Thread(targetT2_job, nameT2)thread_1.start() # 开启T1thread_1.join() thread_2.start() # 开启T2print(all done\n)输出 T1 start T1 finish T2 start all done T2 finish 可以看到T2在等待T1结束后再开始运行。
为了达到预期情况可以使用1221的V型排布
if name main:thread_1 threading.Thread(targetT1_job, nameT1)thread_2 threading.Thread(targetT2_job, nameT2)thread_1.start()thread_2.start()thread_2.join()thread_1.join()print(all done\n)输出 T1 start T2 start T2 finish T1 finish all done 线程通信
在定义的子线程任务函数job中无法通过return的方式将计算完成的结果返回出来。 此时可以使用队列(Queue)这种数据结构来获取子线程的结果数据实现线程之间的通信下面是一个示例
import threading
from queue import Queuedef job(l, q):for i in range(len(l)):l[i] l[i] ** 2q.put(l)def multithreading():q Queue()threads []data [[1, 2, 3], [3, 4, 5], [4, 4, 4], [5, 5, 5]]for i in range(4):t threading.Thread(targetjob, args(data[i], q))t.start()threads.append(t)for thread in threads:thread.join()results []for _ in range(4):results.append(q.get())print(results)if name main:multithreading()线程锁
为了防止多线程输出结果混乱除了添加线程阻塞之外还可以使用线程锁。 同时线程锁还可以确保当前线程执行时内存不会被其他线程访问执行运算完毕后可以打开锁共享内存。
下面是一个不添加线程锁的示例
import threadingdef job1():global Afor i in range(10):A 1print(job1, A)def job2():global Afor i in range(10):A 10print(job2, A)if name main:A 0t1 threading.Thread(targetjob1)t2 threading.Thread(targetjob2)t1.start()t2.start()t1.join()t2.join()输出 job1 1 job1 2 job1 3 job1 4 job1 5 job1 6 job1 7 job1 8 job2job1 19 18 job2 29 job2 39job1 job2 50 job240 60 job2 70 job2 80 job2 90 job2 100 job2 110 添加线程锁之后
import threadingdef job1():global A, locklock.acquire()for i in range(10):A 1print(job1, A)lock.release()def job2():global A, locklock.acquire()for i in range(10):A 10print(job2, A)lock.release()if name main:lock threading.Lock()A 0t1 threading.Thread(targetjob1)t2 threading.Thread(targetjob2)t1.start()t2.start()t1.join()t2.join()输出 job1 1 job1 2 job1 3 job1 4 job1 5 job1 6 job1 7 job1 8 job1 9 job1 10 job2 20 job2 30 job2 40 job2 50 job2 60 job2 70 job2 80 job2 90 job2 100 job2 110 多进程
进程基本结构
import multiprocessing as mpdef job(a, d):print(aaaaa)if name main:p1 mp.Process(targetjob, args(1, 2))p1.start()p1.join()进程通信
和多线程类似进程之间同样可以通过队列queue形式进行通信并且在multiprocessing库中直接包含了Queue()结构。
import multiprocessing as mpdef job(q):res 0for i in range(1000):res i i ** 2 i ** 3q.put(res) # queueif name main:q mp.Queue()p1 mp.Process(targetjob, args(q,))p2 mp.Process(targetjob, args(q,))p1.start()p2.start()p1.join()p2.join()res1 q.get()res2 q.get()print(res1 res2)进程池
进程池(Pool)就是将所要运行的东西放到池子里Python会自行解决多进程的问题。
下面是一个简单示例processes参数指定进程池中的进程数。
import multiprocessing as mpdef job(x):return x * xdef multicore():pool mp.Pool(processes6)# res pool.map(job, range(10))# print(res)res pool.apply_async(job, (2,))print(res.get())if name main:multicore()进程池运算结果有两种获取方式
第一种是pool.map在map()中需要放入函数和需要迭代运算的值然后它会自动分配给CPU核返回结果第二种是pool.apply_async()在apply_async()中只能传递一个值它只会放入一个核进行运算但是传入值时要注意是可迭代的所以在传入值后需要加逗号, 同时需要用get()方法获取返回值。
pool.apply_async()只能传递一个值如果要传递多个值可以使用迭代器下面的代码通过迭代器实现了两种取值方式的等效结果
import multiprocessing as mpdef job(x):return x * xdef multicore():pool mp.Pool(processes2)res pool.map(job, range(10))print(res)res pool.apply_async(job, (2,))# 用get获得结果print(res.get())# 迭代器i0时apply一次i1时apply一次等等multi_res [pool.apply_async(job, (i,)) for i in range(10)]# 从迭代器中取出print([res.get() for res in multi_res])if name main:multicore()进程锁
在不同进程中可以通过变量.value的方式共享变量内存。 如果多个进程对同一个变量进行操控不加进程锁就会让结果混乱。 下面是一个不加进程锁的示例
import multiprocessing as mp
import timedef job(v, num):for _ in range(5):time.sleep(0.1) # 暂停0.1秒让输出效果更明显v.value num # v.value获取共享变量值print(v.value)def multicore():v mp.Value(i, 0) # 定义共享变量p1 mp.Process(targetjob, args(v, 1))p2 mp.Process(targetjob, args(v, 3)) # 设定不同的number看如何抢夺内存p1.start()p2.start()p1.join()p2.join()if name main:multicore()输出 1 2 3 4 7 8 11 14 17 20 添加进程锁之后
import multiprocessing as mp
import timedef job(v, num, l):l.acquire() # 锁住for _ in range(5):time.sleep(0.1)v.value num # 获取共享内存print(v.value)l.release() # 释放def multicore():l mp.Lock() # 定义一个进程锁v mp.Value(i, 0) # 定义共享内存p1 mp.Process(targetjob, args(v, 1, l)) # 需要将lock传入p2 mp.Process(targetjob, args(v, 3, l))p1.start()p2.start()p1.join()p2.join()if name main:multicore()输出 1 2 3 4 5 8 11 14 17 20 进程锁保证了进程p1的完整运行然后才进行了进程p2的运行。
多线程和多进程的效率对比
在python语言中并无法做到实际的多线程这是由于Python中内置了全局解释器锁(GIL)让任何时候只有一个线程进行执行。下面是一段具体解释 尽管Python完全支持多线程编程 但是解释器的C语言实现部分在完全并行执行时并不是线程安全的。 实际上解释器被一个全局解释器锁保护着它确保任何时候都只有一个Python线程执行。 GIL最大的问题就是Python的多线程程序并不能利用多核CPU的优势 比如一个使用了多个线程的计算密集型程序只会在一个单CPU上面运行。 在讨论普通的GIL之前有一点要强调的是GIL只会影响到那些严重依赖CPU的程序比如计算型的。 如果你的程序大部分只会涉及到I/O比如网络交互那么使用多线程就很合适 因为它们大部分时间都在等待。实际上你完全可以放心的创建几千个Python线程 现代操作系统运行这么多线程没有任何压力没啥可担心的。 下面是一段测试程序对比常规计算双线程双进程的计算效率
import multiprocessing as mp
import threading as td
import timedef job(q):res 0for i in range(1000000):res i i ** 2 i ** 3q.put(res) # queuedef multicore():q mp.Queue()p1 mp.Process(targetjob, args(q,))p2 mp.Process(targetjob, args(q,))p1.start()p2.start()p1.join()p2.join()res1 q.get()res2 q.get()print(multicore:, res1 res2)def multithread():q mp.Queue() # thread可放入process同样的queue中t1 td.Thread(targetjob, args(q,))t2 td.Thread(targetjob, args(q,))t1.start()t2.start()t1.join()t2.join()res1 q.get()res2 q.get()print(multithread:, res1 res2)def normal():res 0for _ in range(2):for i in range(1000000):res i i ** 2 i ** 3print(normal:, res)if name main:st time.time()normal()st1 time.time()print(normal time:, st1 - st)multithread()st2 time.time()print(multithread time:, st2 - st1)multicore()print(multicore time:, time.time() - st2)
输出 normal: 499999666667166666000000 normal time: 0.9803786277770996 multithread: 499999666667166666000000 multithread time: 0.9883582592010498 multicore: 499999666667166666000000 multicore time: 1.4371891021728516 结果发现双线程的所花时间和单线程相差不大论证了python的多线程是“伪多线程”。然而多进程的所花时间却更多这是由于该运算较简单启动线程的时间消耗过大。
把计算数扩大十倍输出结果 normal: 4999999666666716666660000000 normal time: 10.019219160079956 multithread: 4999999666666716666660000000 multithread time: 9.802824974060059 multicore: 4999999666666716666660000000 multicore time: 6.478690147399902 此时发现多进程的速度有了明显提升。
- 上一篇: 潍坊高新区建设局门户网站搭建本地环境做网站
- 下一篇: 潍坊企业做网站高权重网站收录问题
相关文章
-
潍坊高新区建设局门户网站搭建本地环境做网站
潍坊高新区建设局门户网站搭建本地环境做网站
- 技术栈
- 2026年04月20日
-
潍坊高端网站设计域名被锁定网站打不开怎么办
潍坊高端网站设计域名被锁定网站打不开怎么办
- 技术栈
- 2026年04月20日
-
潍坊大型网站建设上海网站免费制作
潍坊大型网站建设上海网站免费制作
- 技术栈
- 2026年04月20日
-
潍坊企业做网站高权重网站收录问题
潍坊企业做网站高权重网站收录问题
- 技术栈
- 2026年04月20日
-
潍坊市坊子区建设局网站中国建设银行个人网上银行登录
潍坊市坊子区建设局网站中国建设银行个人网上银行登录
- 技术栈
- 2026年04月20日
-
潍坊市建设工程管理处网站wordpress app端
潍坊市建设工程管理处网站wordpress app端
- 技术栈
- 2026年04月20日






