经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » Python » 查看文章
Python中的多线程实例(简单易懂)
来源:jb51  时间:2022/6/20 17:07:32  对本文有异议

前言:

多线程简单理解就是:一个CPU,也就是单核,将时间切成一片一片的,CPU轮转着去处理一件一件的事情,到了规定的时间片就处理下一件事情。

1.python中显示当前线程信息的属性和方法

  1. # coding:utf-8
  2. # 导入threading包
  3. import threading
  4. if __name__ == "__main__":
  5. print("当前活跃线程的数量", threading.active_count())
  6. print("将当前所有线程的具体信息展示出来", threading.enumerate())
  7. print("当前的线程的信息展示", threading.current_thread())

效果图:

在这里插入图片描述

2.添加一个线程

  1. # coding:utf-8
  2. import threading
  3. import time
  4. def job1():
  5. # 让这个线程多执行几秒
  6. time.sleep(5)
  7. print("the number of T1 is %s" % threading.current_thread())
  8. if __name__ == "__main__":
  9. # 创建一个新的线程
  10. new_thread = threading.Thread(target=job1, name="T1")
  11. # 启动新线程
  12. new_thread.start()
  13. print("当前线程数量为", threading.active_count())
  14. print("所有线程的具体信息", threading.enumerate())
  15. print("当前线程具体信息", threading.current_thread())

效果图:

在这里插入图片描述

3.线程中的join函数

(1)预想的是,执行完线程1,然后输出All done…“理想很丰满,现实却不是这样的”

  1. # coding:utf-8
  2. import threading
  3. import time
  4. def job1():
  5. print("T1 start")
  6. for i in range(5):
  7. time.sleep(1)
  8. print(i)
  9. print("T1 finish")
  10. def main():
  11. # 新创建一个线程
  12. new_thread = threading.Thread(target=job1, name="T1")
  13. # 启动新线程
  14. new_thread.start()
  15. print("All done...")
  16. if __name__ == "__main__":
  17. main()

效果图:

在这里插入图片描述

(2)为了达到我们的预期,我们使用join函数,将T1线程进行阻塞。join函数进行阻塞是什么意思?就是哪个线程使用了join函数,当这个线程正在执行时,在他之后的线程程序不能执行,得等这个被阻塞的线程全部执行完毕之后,方可执行!

  1. # coding:utf-8
  2. import threading
  3. import time
  4. def job1():
  5. print("T1 start")
  6. for i in range(5):
  7. time.sleep(1)
  8. print(i)
  9. print("T1 finish")
  10. def main():
  11. # 新创建一个线程
  12. new_thread = threading.Thread(target=job1, name="T1")
  13. # 启动新线程
  14. new_thread.start()
  15. # 阻塞这个T1线程
  16. new_thread.join()
  17. print("All done...")
  18. if __name__ == "__main__":
  19. main()

效果图:

在这里插入图片描述

4.使用Queue存储线程的结果

线程的执行结果,无法通过return进行返回,使用Queue存储。

  1. # coding:utf-8
  2. import threading
  3. from queue import Queue
  4. """
  5. Queue的使用
  6. """
  7. def job(l, q):
  8. for i in range(len(l)):
  9. l[i] = l[i] ** 2
  10. q.put(l)
  11. def multithreading():
  12. # 创建队列
  13. q = Queue()
  14. # 线程列表
  15. threads = []
  16. # 二维列表
  17. data = [[1, 2, 3], [4, 5, 6], [7, 8, 9], [6, 6, 6]]
  18. for i in range(4):
  19. t = threading.Thread(target=job, args=(data[i], q))
  20. t.start()
  21. threads.append(t)
  22.  
  23. # 对所有线程进行阻塞
  24. for thread in threads:
  25. thread.join()
  26. results = []
  27. # 将新队列中的每个元素挨个放到结果列表中
  28. for _ in range(4):
  29. results.append(q.get())
  30. print(results)
  31. if __name__ == "__main__":
  32. multithreading()

效果图:

在这里插入图片描述

5.线程锁lock

当同时启动多个线程时,各个线程之间会互相抢占计算资源,会造成程序混乱。

举个栗子:

当我们在选课系统选课时,当前篮球课还有2个名额,我们三个人去选课。

选课顺序为stu1 stu2 stu3,应该依次打印他们三个的选课过程,但是现实情况却是:

  1. # coding:utf-8
  2. import threading
  3. import time
  4.  
  5. def stu1():
  6. print("stu1开始选课")
  7. global course
  8. if course > 0:
  9. course -= 1
  10. time.sleep(2)
  11. print("stu1选课成功,现在篮球课所剩名额为%d" % course)
  12. else:
  13. time.sleep(2)
  14. print("stu1选课失败,篮球课名额为0,请选择其他课程")
  15. def stu2():
  16. print("stu2开始选课")
  17. global course
  18. if course > 0:
  19. course -= 1
  20. time.sleep(2)
  21. print("stu2选课成功,现在篮球课所剩名额为%d" % course)
  22. else:
  23. time.sleep(2)
  24. print("stu2选课失败,篮球课名额为0,请选择其他课程")
  25.  
  26. def stu3():
  27. print("stu3开始选课")
  28. global course
  29. if course > 0:
  30. course -= 1
  31. time.sleep(2)
  32. print("stu3选课成功")
  33. print("篮球课所剩名额为%d" %course)
  34. else:
  35. time.sleep(2)
  36. print("stu3选课失败,篮球课名额为0,请选择其他课程")
  37. if __name__ == "__main__":
  38. # 篮球课名额
  39. course = 2
  40. T1 = threading.Thread(target=stu1, name="T1")
  41. T2 = threading.Thread(target=stu2, name="T2")
  42. T3 = threading.Thread(target=stu3, name="T3")
  43. T1.start()
  44. T2.start()
  45. T3.start()

效果图:

在这里插入图片描述

为了解决这种情况,我们使用lock线程同步锁,在线程并发执行时,保证每个线程执行的原子性。有效防止了共享统一数据时,线程并发执行的混乱。

改进的代码如下:

  1. # coding:utf-8
  2. import threading
  3. import time
  4. def stu1():
  5. global lock
  6. lock.acquire()
  7. print("stu1开始选课")
  8. global course
  9. if course > 0:
  10. course -= 1
  11. time.sleep(2)
  12. print("stu1选课成功,现在篮球课所剩名额为%d" % course)
  13. else:
  14. time.sleep(2)
  15. print("stu1选课失败,篮球课名额为0,请选择其他课程")
  16. lock.release()
  17.  
  18.  
  19. def stu2():
  20. global lock
  21. lock.acquire()
  22. print("stu2开始选课")
  23. global course
  24. if course > 0:
  25. course -= 1
  26. print("stu2选课成功,现在篮球课所剩名额为%d" % course)
  27. else:
  28. time.sleep(1)
  29. print("stu2选课失败,篮球课名额为0,请选择其他课程")
  30. lock.release()
  31.  
  32. def stu3():
  33. global lock
  34. lock.acquire()
  35. print("stu3开始选课")
  36. global course
  37. if course > 0:
  38. course -= 1
  39. time.sleep(1)
  40. print("stu3选课成功,现在篮球课所剩名额为%d" % course)
  41. else:
  42. time.sleep(1)
  43. print("stu3选课失败,篮球课名额为0,请选择其他课程")
  44. lock.release()
  45.  
  46. if __name__ == "__main__":
  47. # 篮球课名额
  48. course = 2
  49. # 创建同步锁
  50. lock = threading.Lock()
  51. T1 = threading.Thread(target=stu1, name="T1")
  52. T2 = threading.Thread(target=stu2, name="T2")
  53. T3 = threading.Thread(target=stu3, name="T3")
  54. T1.start()
  55. T2.start()
  56. T3.start()

效果图:

在这里插入图片描述

到此这篇关于Python中的多线程实例(简单易懂)的文章就介绍到这了,更多相关Python多线程内容请搜索w3xue以前的文章或继续浏览下面的相关文章希望大家以后多多支持w3xue!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号