1.1 什么是多线程?

多线程 Threading 是一种让程序拥有分身效果. 能同时处理多件事情. 一般的程序只能从上到下一行行执行代码, 不过 多线程 (Threading) 就能打破这种限制. 让你的程序鲜活起来.

1.2 添加多线程

  1. import threading
  2. def thread_job():
  3. print("我是被添加的线程, 名称是: %s"% threading.current_thread())
  4. def main():
  5. added_thread = threading.Thread(target=thread_job) # 添加线程(定义线程)
  6. added_thread.start() # 启动线程
  7. print(threading.active_count()) # 查看当前可运行几个线程!
  8. print(threading.enumerate()) # 查看当前运行了那几个线程? MainThread 表示主进程, Thread 表示扩展的进程
  9. print(threading.current_thread()) # 查看当前运行的线程是那个?
  10. if __name__ == '__main__':
  11. main()

1.3 join() 功能

join()的功能 等待该线程结束

  1. # 多线程
  2. import threading
  3. import time
  4. def thread_job():
  5. print(f"T1 start\n")
  6. for i in range(10):
  7. time.sleep(0.1)
  8. print(f"T1 finish\n")
  9. def T2_job():
  10. print(f"T2 start\n")
  11. print(f"T2 finish\n")
  12. def main():
  13. # print(threading.active_count()) # 查看当前可运行几个线程!
  14. # print(threading.enumerate()) # 查看当前运行了那几个线程? MainThread 表示主进程, Thread 表示扩展的进程
  15. # print(threading.current_thread()) # 查看当前运行的线程是那个?
  16. added_thread = threading.Thread(target=thread_job, name="T1")
  17. thread2 = threading.Thread(target=T2_job, name="T2")
  18. added_thread.start()
  19. thread2.start()
  20. added_thread.join() # 等待这个线程结束
  21. thread2.join() # 等待这个线程结束
  22. print("all done\n")
  23. """
  24. 有时候 t2 的线程比 t1 的线程 先结束, 因为t2的线程做的任务比较简单
  25. """
  26. if __name__ == '__main__':
  27. main()

1.4 存储进程结果 Queue

  1. # 多线程 queue
  2. """
  3. 问题1: 在多线程当中,它是不能返回出来一个值的, 那么怎么解决?
  4. 使用 模块 queue 和大写的 Queue
  5. """
  6. import threading
  7. import time
  8. from queue import Queue
  9. def job(l,q):
  10. # 对每一个列表的值进行 2次方计算
  11. for i in range(len(l)):
  12. l[i] = l[i]**2
  13. q.put(l)
  14. def multithreading():
  15. q = Queue()
  16. threads = []
  17. data = [[1,2,3],[3,4,5],[4,4,4],[5,5,5]]
  18. for i in range(4):
  19. t = threading.Thread(target=job, args=(data[i],q))
  20. t.start()
  21. # 把启动的线程 都加入到列表中
  22. threads.append(t)
  23. # 批量 等待线程结束, 结束之后,会把每个线程的返回数据 保存在q里
  24. for thread in threads:
  25. thread.join()
  26. results = [] # 定义1个空的变量用来保存 多线程(每个线程返回的值)
  27. for _ in range(4):
  28. results.append(q.get()) # 取出每个线程的值
  29. print(results)
  30. if __name__ == '__main__':
  31. multithreading()

打印: [[1, 4, 9], [9, 16, 25], [16, 16, 16], [25, 25, 25]]

1.5 GIL 不一定有效率

1.6 线程锁 Lock

如果不设置 线程锁, 则会打印的数据很乱

  1. # 线程锁
  2. """
  3. 引用 lock = threading.Lock()
  4. 加锁 lock.acquire()
  5. 解锁 lock.release()
  6. """
  7. import threading
  8. def job1():
  9. global A, lock
  10. lock.acquire()
  11. for i in range(10):
  12. A += 1
  13. print("job1", A)
  14. lock.release()
  15. def job2():
  16. global A, lock
  17. lock.acquire()
  18. for i in range(10):
  19. A += 10
  20. print("job2", A)
  21. lock.release()
  22. if __name__ == '__main__':
  23. lock = threading.Lock()
  24. A =0;
  25. t1 = threading.Thread(target=job1)
  26. t2 = threading.Thread(target=job2)
  27. t1.start()
  28. t2.start()
  29. t1.join()
  30. t2.join()