主要是证明几个线程的注意事项
第一次接触互斥锁
算是实战性能高的函数!非常有用
死锁只是刚刚了解一点
"""
线程进程执行都是无序的
主线程会等待所有子线程结束再结束
线程之间共享全局变量
"""
import threading
import time
def task1():
time.sleep(1)
print(threading.current_thread())
def task2():
while True:
print("任务执行中...")
time.sleep(0.3)
# 定义全局变量
g_list = []
g_num = 0 # 不可变类型,不能在原有基础上修改数值,必须新开辟一个内存地址
"""互斥锁:为了保证只有一个线程运行,那个线程抢到这个锁就能使用共享数据"""
# 创建锁,Lock是一个函数,通过调用
lcok = threading.Lock()
# 共享数据上锁
# 释放锁(不然会发生死锁)
def add_data():
for i in range(3):
# 每循环一次把数据添加到全局变量
g_list.append(i)
print("add:", i)
time.sleep(0.2)
print("achieve the tast.", g_list)
# 读取数据任务
def read_data():
print("read:", g_list)
def test3():
# 上锁,之后其他线程就要等着
lcok.acquire()
for i in range(100000):
global g_num # 表示要声明修改全局变量的内存地址
# 若是省略了,最后只会输出0
g_num = g_num + 1 # 每循环一次加一
# 代码执行到此,说明数据计算完成
print("test3:", g_num)
# 释放锁
lcok.release()
def test4():
lcok.acquire()
for i in range(100000):
global g_num
# 若是省略了,最后只会输出0
g_num = g_num + 1 # 每循环一次加一
# 代码执行到此,说明数据计算完成
print("test4:", g_num)
lcok.release()
"""
if __name__ =='__main__':
# 循环创建大量线程,测量线程之间执行是否无序
for i in range(20):
# 每循环一次创建一个子线程:20个
sub_thread = threading.Thread(target=task1)
# 启动子线程
sub_thread.start()
"""
"""
if __name__ =='__main__':
# daemon =True 表示创建的子线程守护主线程,主线程退出子系统直接销毁
sub_thread = threading.Thread(target=task2, daemon=True) # 达到退出效果:方法一
# sub_thread = threading.Thread(target=task2)
# sub_thread.setDaemon(True)
# 把子线程设置成为守护主线程
sub_thread.start()
time.sleep(1) # 理论上执行四次
print("over")
exit() # 强制退出(但是在这里也退出不了,在等待子线程结束)
"""
"""
if __name__ == '__main__':
# create a child process of add_thread
add_thread = threading.Thread(target=add_data())
# create a subprocess of read_thread
read_thread = threading.Thread(target=read_data())
# start the thread to execute the corresponding program
add_thread.start()
time.sleep(1)
# 当前线程(主线程)等待添加数据的子线程执行完成以后代码在继续执行
add_thread.join()
read_thread.start()
"""
if __name__ == '__main__':
first_thread = threading.Thread(target=test3)
second_thread = threading.Thread(target=test4)
# 这种情况下代码一样,但是执行结果不一样,因为两个线程同时执行
# 避免这样,就要让一个线程等待(线程同步:保证同一时刻只有一个线程在操作)
# 线程同步两种方式:线程等待、互斥锁
first_thread.start()
# first_thread.join() # 线程同步方式一:等待第一个子线程执行完毕在执行第二个
second_thread.start()
# 用互斥锁,执行顺序人为不能决定
# 保证了数据准确性,但是执行性能下降(火车站众多售票口,一定会在减一时上锁!!)
# 不想让数据出现问题,就用互斥锁;要上锁就要全上,若是一个上锁了另外不上锁的还是自己执行自己的