1.多线程的使用:
#1.导入线程模块
import threading
import time
def sing():
#获取当前线程
current_thread = threading.current_thread()
print("sing:", current_thread)
for i in range(3):
print("唱歌中...")
time.sleep(0.2)
def dance():
#获取当前线程
current_thread = threading.current_thread()
print("dance:", current_thread)
for i in range(3):
print("跳舞中...")
time.sleep(0.2)
if __name__ == '__main__':
#获取当前线程
current_thread = threading.current_thread()
print("main_thread:", current_thread)
#2.创建子线程
sing_thread = threading.Thread(target=sing, name="sing_thread")
dance_thread = threading.Thread(target=dance, name="dance_thread")
#3.启动子线程执行对应的任务
sing_thread.start()
dance_thread.start()
2.线程执行带有参数的任务:
import threading
def show_info(name, age):
print("name: %s age: %d" % (name, age))
if __name__ == '__main__':
# #创建子线程
# #以元组方式传参,要保证元组里元素的顺序和函数的参数顺序一致
# sub_thread = threading.Thread(target=show_info, args=("李四", 20))
# #启动线程执行对应的任务
# sub_thread.start()
#以字典的方式传参,要保证字典里的key和函数的参数名保持一致
sub_thread = threading.Thread(target=show_info, kwargs={"name": "王五", "age": 30})
##启动线程执行对应的任务
sub_thread.start()
3.线程之间的执行是无序的:
import threading
import time
def task():
time.sleep(1)
#获取当前线程
print(threading.current_thread())
if __name__ == '__main__':
#循环创建大量线程,测试线程之间是否无序
for i in range(20):
#每循环一次创建一个子线程
sub_thread = threading.Thread(target=task)
#启动子线程执行对应的任务
sub_thread.start()
#线程之间执行是无序的
4.线程之间共享全局变量:
import threading
import time
#定义全局变量
g_list = []
#添加数据的任务
def add_data():
for i in range(3):
#每循环一次把数据添加到全局变量
g_list.append(i)
print("add:", i)
time.sleep(0.2)
#代码执行到此,说明添加数据完成
print("添加数据完成:", g_list)
#读取数据的任务
def read_data():
print(g_list)
if __name__ == '__main__':
#创建添加数据的子线程
add_thread = threading.Thread(target=add_data)
#创建读取数据的子线程
read_thread = threading.Thread(target=read_data)
#启动线程执行对应的任务
add_thread.start()
#time.sleep(1)
#当前线程等待添加数据的子线程执行完成以后代码在继续执行
add_thread.join()
read_thread.start()
#结论:线程之间共享全局变量
5.互斥锁:
import threading
#全局变量
g_num = 0
#创建互斥锁
lock = threading.Lock()
#循环100万次执行的任务
def task1():
#上锁
lock.acquire()
for i in range(1000000):
global g_num
g_num = g_num + 1
#代码执行到此,说明数据计算完成
print("task1:", g_num)
#释放锁
lock.release()
def task2():
#上锁
lock.acquire()
for i in range(1000000):
#每循环一次给全局变量+1
global g_num
g_num = g_num + 1
#代码执行到此,说明数据计算完成
print("task2:", g_num)
#释放锁
lock.release()
if __name__ == '__main__':
#创建两个子线程
first_thread = threading.Thread(target=task1)
second_thread = threading.Thread(target=task2)
#启动线程执行任务
first_thread.start()
#线程等待,让第一个线程先执行,第二个线程后执行,保证数据不会有问题
second_thread.start()
#互斥锁可以保证同一时刻只有一个线程去执行代码,能够保证全局变量的数据没有问题
#线程等待和互斥锁都是把多任务改成单任务去执行,保证了数据的准确性,但是执行性会下降
6.死锁:
#死锁:一直等待对方释放锁
import threading
#创建互斥锁
lock = threading.Lock()
#需求:多线程同时根据下标在列表中取值,要保证同一时刻只能有一个线程去取值
def get_value(index):
#上锁
lock.acquire()
my_list = [1, 4, 6]
#判断下标是否越界
if index >= len(my_list):
print("下标越界:", index)
#取值不成功,也需要释放互斥锁,不要影响后面的线程去取值
#锁需要在合适的地方进行释放,防止死锁
lock.release()
return
#根据下标取值
value = my_list[index]
print(value)
#释放锁
lock.release()
if __name__ == '__main__':
#创建大量线程,同时执行根据下标取值的任务
for i in range(10):
#每循环一次,创建一个子线程
sub_thread = threading.Thread(target=get_value, args=(i,))
#启动线程执行任务
sub_thread.start()