线程是执行代码的一个分支,每个执行分支想要工作执行代码都需要cpu进行调度,也就是说线程是cpu进行调度的基本单位,每个进程至少有一个线程
多线程可以完成多任务
线程模块:threading
#coding:utf-8 2 #导入线程模块 3 import threading 4 """ 5 线程类Thread参数说明 6 Thread(group,target,name,args,kwargs) 7 .group:线程组目前只能使用None 8 .target:执行的目标文件名或者函数名 9 .args:元组进行传参 10 .kwargs:字典进行传参 11 .name:线程名,一般不用进行设置 12 启动线程 13 start()方法 14 """ 15 import time 16 17 def tread1(): 18 for i in range(3): 19 print("吃饭") 20 time.sleep(0.2) 21 def tread2(): 22 for i in range(3): 23 print("散步") 24 time.sleep(0.2) 25 26 if __name__ == "__main__": 27 #创建两条子线程 28 tread_1 = threading.Thread(target = tread1) 29 tread_2 = threading.Thread(target = tread2) 30 tread_1.start() 31 tread_2.start() 32 #运行结果 吃饭 散步 吃饭 散步 吃饭 散步
#线程之间的执行是无序的 2 import threading 3 import time 4 def task(): 5 #获取当前线程 6 time.sleep(1) 7 print(threading.current_thread()) 8 if __name__ == "__main__": 9 #循环创建大量线程,测试线程之间的执行是无序的 10 for i in range(20): 11 sub_thread = threading.Thread(target = task) 12 sub_thread.start() 13 #线程之间的执行是无序的,具体是那个线程执行是由cpu进行调度 ~ #运行结果 <Thread(Thread-5, started 140423150434048)> <Thread(Thread-3, started 140423373272832)> <Thread(Thread-1, started 140423390058240)> <Thread(Thread-2, started 140423381665536)> <Thread(Thread-4, started 140423364880128)>
#线程之间共享全局变量 2 #因为线程都在同一个进程中,并没有创建新的进程 3 import threading 4 import time 5 6 g_list = list() 7 def add_date(): 8 for i in range(3): 9 print("add:",i) 10 g_list.append(i) 11 time.sleep(0.2) 12 13 def read_date(): 14 print("读取的数据:",g_list) 15 16 17 if __name__ == "__main__": 18 add_thread = threading.Thread(target = add_date) 19 read_thread = threading.Thread(target = read_date) 20 add_thread.start() 21 add_thread.join() 22 read_thread.start() 23 24 #线程之间可以共享全局变量 ~ #运行结果 add: 0 add: 1 add: 2 读取的数据: [0, 1, 2]
#线程之间共享数据出现错误问题,解决办法互斥锁 2 import threading 3 import time 4 5 g_number = 0#全局变量 6 #创建互斥锁,Lock本质上是一个函数 7 lock = threading.Lock() 8 def test1(): 9 #共享数据上锁 10 lock.acquire() 11 for i in range(1000000): 12 global g_number#修改全局变量的地址 13 g_number += 1 14 print("test1",g_number) 15 #释放锁,不释放则会造成死锁 16 lock.release() 17 def test2(): 18 lock.acquire() 19 #以下代码保证只有一个线程进行 20 for i in range(1000000): 21 global g_number#修改全局变量的地址 22 g_number += 1 23 print("test2",g_number) 24 lock.release() 25 def test3(): 26 lock.acquire() 27 for i in range(1000000): 28 global g_number#修改全局变量的地址 29 g_number += 1 30 print("test3",g_number) 31 lock.release() 32 #互斥锁的使用 33 34 if __name__ == "__main__": 35 #创建两个子线程 36 first_thread = threading.Thread(target = test1) 37 sencond_thread = threading.Thread(target = test2) 38 three_thread = threading.Thread(target = test3) 39 first_thread.start() 40 sencond_thread.start() 41 three_thread.start() 42 #线程等待和互斥锁都是为类保证一次只有一次进程在运行 #运行结果 test3 2999993 test3 2999994 test3 2999995 test3 2999996 test3 2999997 test3 2999998 test3 2999999 test3 3000000
#如果对共享数据不进行解锁则岁造成死锁 2 #死锁会导致程序一直处于等待的状态 3 import threading 4 #创建锁 5 lock = threading.Lock() 6 7 def get_value(index): 8 my_list = [1,2,3] 9 #对数据进行上锁 10 lock.acquire() 11 #对下标进判断算是否越界 12 if index >= len(my_list): 13 print("下表越界:",index) 14 return 15 value = my_list[index] 16 print(index) 17 #对数据进行解锁 18 lock.release() 19 20 if __name__ == "__main__": 21 for i in range(10): 22 child_thread = threading.Thread(target = get_value, args = (i,)) 23 child_thread.start() ~ #运行结果 0 1 2 下表越界: 3 程序一直处于等待状态 ~