概念
并发: 指的是任务数多于cpu核数,通过操作系统的各种任务调度算法,实现用多个任务“一起”执行(实际上总有一些任务不在执行,因为切换任务的速度相当快,看上去一起执行而已
并行:指的是任务数小于等于cpu核数,即任务真的是一起执行的
线程: 线程就是在程序运行过程中,执行程序代码的一个分支,每个运行的程序至少都有一个线程
线程实现代码
import threading
import time
# 唱歌任务
def sing():
# 扩展: 获取当前线程
for i in range(3):
print("正在唱歌...%d" % i)
time.sleep(1)
# 跳舞任务
def dance():
# 扩展: 获取当前线程
for i in range(3):
print("正在跳舞...%d" % i)
time.sleep(1)
if __name__ == '__main__':
# 创建唱歌的线程
sing_thread = threading.Thread(target=sing)
# 创建跳舞的线程
dance_thread = threading.Thread(target=dance)
# 开启线程
sing_thread.start()
dance_thread.start()
守护主线程
线程执行的时候,主线程是需要等待子线程执行完后再结束的。如果需要主线程不等待子线程(即,如果主线程结束,那么子线程直接结束),那么可以设置守护主线程。有两种方法可以实现守护主线程
# 方式1
sub_thread = threading.Thread(target=show_info, daemon=True)
# 方式2
sub_thread.setDaemon(True)
线程等待
主线程等待第一个线程执行完成以后代码再继续执行,让其执行第二个线程。解决多线程同时对全局变量操作数据发生了错误的问题。
# 启动线程
first_thread.start()
# 线程同步: 一个任务执行完成以后另外一个任务才能执行,同一个时刻只有一个任务在执行
first_thread.join()
# 启动线程
second_thread.start()
互斥锁
概念:对共享数据进行锁定,保证同一时刻只能有一个线程操作。同样也是解决多线程同时对全局变量操作数据发生了错误的问题。
提示:加上互斥锁,那个线程抢到这个锁我们决定不了,那线程抢到锁那个线程先执行,没有抢到的线程需要等待; 加上互斥锁多任务瞬间变成单任务,性能会下降,也就是说同一时刻只能有一个线程去执行
import threading
g_num = 0
# 创建全局互斥锁
lock = threading.Lock()
def sum_num1():
lock.acquire() # 上锁
for i in range(1000000):
global g_num
g_num += 1
print("sum1:", g_num)
lock.release() # 释放锁
def sum_num2():
lock.acquire() # 上锁
for i in range(1000000):
global g_num
g_num += 1
print("sum2:", g_num)
lock.release() # 释放锁
if __name__ == '__main__':
threading.Thread(target=sum_num1).start()
threading.Thread(target=sum_num2).start()