线程简介
-
在一个进程中,若想做多个子任务,我们把这些子任务称为线程。
-
线程可以理解为轻量级的进程。
-
进程之间的数据是独立的,而一个进程下的线程数据是共享的。
-
线程是CPU分配时间的最小单位。进程和线程的调度都是操作系统的事。
-
一个进程默认都有一个线程,我们称为主线程。
线程模块
-
_thread:低级模块
-
threading:高级模块,是对_thread的封装
-
以后建议大家使用高级模块threading
线程模块_thread
-
示例:
import _thread import time def loop(): print('子线程开始') print('子线程结束') if __name__ == '__main__': print('主线程开始') # 创建线程 _thread.start_new_thread(loop, ()) # 主线程结束,子线程立即结束,通过演示测试 time.sleep(3) print('主线程结束')
非常简陋,不建议使用
线程模块threading
-
基本使用
import threading import time def run(num): c = threading.current_thread() print('子线程开始', c.name) time.sleep(3) print(num) # print(threading.active_count()) print('子线程结束', c.name) if __name__ == '__main__': # 获取主线程 t = threading.main_thread() print('主线程开始:', t.name) # 获取当前线程 # c = threading.current_thread() # print('当前线程:', c.name) # 创建子线程 sub = threading.Thread(target=run, args=(250,), name='下载美女图片') # 启动子线程 sub.start() # 活跃线程个数 # print(threading.active_count()) # 线程列表 # print(threading.enumerate()) time.sleep(1) # 判断线程是否是活着的 print(sub.is_alive()) # 等待子线程 sub.join() print(sub.is_alive()) print('主线程结束:', t.name)
数据共享
-
示例:全局变量可以共享
import threading # 全局变量 num = 250 def thread_one(): global num num += 10 def thread_two(): global num num -= 100 if __name__ == '__main__': print('主线程:', num) t1 = threading.Thread(target=thread_one) t1.start() t1.join() print('主线程:', num) t2 = threading.Thread(target=thread_two) t2.start() t2.join() print('主线程:', num)
线程之间共享进程的所有数据
-
示例:多线程操作同一变量,可能会出错,代码见
04-gongxiang.py
-
示例:加锁解决数据错乱问题(线程锁)
-
import threading # 这是你银行的存款 money = 250 def run(n): global money for i in range(100000): ''' lock.acquire() try: # 运算之后,数据应该不变 money = money + n money = money - n finally: lock.release() ''' # 简化书写 with lock: money = money + n money = money - n if __name__ == '__main__': lock = threading.Lock() # while True: t1 = threading.Thread(target=run, args=(10,)) t2 = threading.Thread(target=run, args=(15,)) t1.start() t2.start() t1.join() t2.join() # if money != 250: # break print(money)