Thread线程

线程和进程

线程是进程中执行代码的一个分支,每个执行分支(线程)要想工作执行代码需要cpu进行调度,也就是说线程是cpu调度的基本单位,每个进程至少都有一个线程,而这个线程就是我们通常说的主线程。

区别对比

  1. 进程之间不共享全局变量
  2. 线程之间共享全局变量,但是要注意资源竞争的问题,解决办法: 线程同步
  3. 创建进程的资源开销要比创建线程的资源开销要大
  4. 进程是操作系统资源分配的基本单位,线程是CPU调度的基本单位
  5. 线程不能够独立执行,必须依存在进程中
  6. 多进程开发比单进程多线程开发稳定性要强

优缺点对比

  • 进程优缺点:
    • 优点:可以用多核
    • 缺点:资源开销大
  • 线程优缺点:
    • 优点:资源开销小
    • 缺点:不能使用多核

小结

  • 进程和线程都是完成多任务的一种方式
  • 多进程要比多线程消耗的资源多,但是多进程开发比单进程多线程开发稳定性要强,某个进程挂掉不会影响其它进程。
  • 多进程可以使用cpu的多核运行,多线程可以共享全局变量。
  • 线程不能单独执行必须依附在进程里面

线程的参数

线程类Thread参数说明

  • group: 线程组,目前只能使用None
  • target: 执行的目标任务名
  • args: 以元组的方式给执行任务传参
  • kwargs: 以字典方式给执行任务传参
  • name: 线程名,一般不用设置

线程使用方式

  1. 导入线程模块
    • import threading
  2. 创建子线程并指定执行的任务
    • sub_thread = threading.Thread(target=任务名)
  3. 启动线程执行任务
    • sub_thread.start()
  4. args 表示以元组的方式给执行任务传参
  5. kwargs 表示以字典方式给执行任务传参
  6. 线程执行执行是无序的
  7. 主线程默认会等待所有子线程执行结束再结束,设置守护主线程的目的是主线程退出子线程销毁。
  8. 线程之间共享全局变量,好处是可以对全局变量的数据进行共享。
  9. 线程之间共享全局变量可能会导致数据出现错误问题,可以使用线程同步方式来解决这个问题。
    • 线程等待(join)

线程使用案例(在代码中体会线程的概念)

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
# 进程是资源分配的最小单位,线程是CPU调度的最小单位(一个进程会有多个线程如QQ是个进程,里面有聊天线程,语音通话线程)
# 线程的使用
import threading
import time

list1= list() # 创建一个空列表list1

def sing(count):
print("当前执行的线程为:",threading.current_thread()) # 获取当前线程的名称
for i in range(count):
print(f"唱歌第{i+1}次")
time.sleep(1)

def dance(count):
print("当前执行的线程为:", threading.current_thread()) # 获取当前线程的名称
for i in range(count):
print(f"跳舞第{i+1}次")
time.sleep(1)

def add_data():
for i in range(10):
list1.append(i) # 将元素添加到列表末尾

def read_data():
for i in list1:
print(i)

if __name__ == '__main__':
sing_thread = threading.Thread(target=sing,kwargs={'count':5}) # 创建唱歌线程,并用kwargs传参
dance_thread = threading.Thread(target=dance,args=(5,),daemon=True) # 创建跳舞线程,用args传参,并设置守护主线程
sing_thread.setDaemon(True) # 设置成为守护主线程,主线程退出后子线程直接销毁不再执行子线程

sing_thread.start() # 线程开始
dance_thread.start() # 线程开始

time.sleep(0.1)
print("over") # 这里没等线程执行完就到了这一句,但是程序不会退出。说明主线程会等待所有的子线程执行结束再结束

# 设置守护主线程(守护主线程就是主线程退出子线程销毁不再执行)
# 两种方式 1,threading.Thread(target=show_info, daemon=True) 2,线程对象.setDaemon(True)

write_thread = threading.Thread(target=add_data)
read_thread = threading.Thread(target=read_data)
write_thread.start()
# 使用线程同步(防止数据不一致)
write_thread.join() # 主线程等待写入线程执行完成以后代码在继续往下执行
print("开始读取数据啦")
read_thread.start() # 结果成功打印出数据表明线程之间共享全局变量