import threading # 加载线程库import timedefworker():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,9):time.sleep(1)print("welcome to study python!")defworker_1():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,9):time.sleep(1)print("welcome to study threading……!")t = threading.Thread(target=worker)# 对线程库中的类进行实例化,指定线程调用的函数
t.start()#启动线程,线程启动之后,不杀死线程的情况下# 要将目标函数执行完才能结束t = threading.Thread(target=worker_1)
t.start()# 并发运行,有两个函数,启动两个线程
代码解析:
通过threading.Thread创建一个线程对象,target是目标函数
线程启动调用start方法
并发调用多个函数,就需要启动两个线程,分别对应不同的函数,已达到并发的效果
线程的退出和传参
python中,没有提供线程退出的方法,线程会在下面情况下退出
线程函数内语句执行完毕
线程函数中抛出未处理的异常
python中的线程没有优先级,没有线程组的概念,也不能被销毁,停止,挂起,因此也就没有恢复和中断
线程的传参和函数的传参没有区别,其本质上就是函数传参,实参传元祖,关键字参数传字典
threading的属性和方法
current_thread:返回当前线程的对象
main_thread:返回主线程的对象
active_count:当前处于alive状态的线程个数
enumerate:返回所有或者的线程列表
包括已经终止的线程和未开始的线程
get_ident:返回当前线程的ID,非0 整数
import threading # 加载线程库import timedefworker():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,3):time.sleep(1)print("welcome to study python!")print(threading.current_thread())print(threading.active_count())print(threading.enumerate())print(threading.get_ident())
t = threading.Thread(target=worker)
t.start()# 并发运行,有两个函数,启动两个线程
threading实例的属性和方法
线程的name只是一个名称,可以重复,但是ID必须唯一,不过ID可以在退出线程之后再利用
name:只是线程的一个名字,或者可以理解为一个标识
ident:线程ID,是一个非0 整数
线程启动之后才会有ID,否则为None
线程退出之后,ID依旧可以访问
ID可以重复利用
is_alive:返回线程是否活着,是一个布尔值
start:启动线程,每一个线程必须且只能执行该方法一次
run:运行线程函数
使用start方法启动线程,是启动了一个新的线程
但是使用run方法,并没有启动新的线程,就是在主线程中调用了一个普通的函数
因此,启动线程需要使用start方法,可以启动多个线程
import threading # 加载线程库import timedefworker():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,3):time.sleep(1)print("welcome to study python!")t = threading.Thread(target=worker)
t.start()# 并发运行,有两个函数,启动两个线程print(t.name)print(t.ident)print(t.is_alive())print(time.sleep(10))print(t.name)print(t.ident)print(t.is_alive())**********************run_result*******************
Thread-114664True
welcome to study python!
welcome to study python!
welcome to study python!
None
Thread-114664False
import threading # 加载线程库import timeglobal_data = threading.local()# 创建实例,实现线程之间的全局作用域,线程之间互不影响defworker():global_data.x =0# 给实例创建一个x的属性for i inrange(100):time.sleep(0.0001)global_data.x +=1print(threading.current_thread(),global_data.x)for i inrange(5):threading.Thread(target=worker).start()***************************使用global实现,会相互影响******************
x =0defworker():global xfor i inrange(100):time.sleep(0.0001)x +=1print(threading.current_thread(),x)for i inrange(5):threading.Thread(target=worker).start()
# 老板让员工生产10个杯子之后,停止,说good jobfrom threading import Event,Thread
import logging
import timeFORMAT ="%(asctime)s-%(threadName)s-%(thread)d-%(message)s"
logging.basicConfig(format=FORMAT,level=logging.INFO)defboss(event:Event):logging.info("i am boss waittinng for you")event.wait()# 等待,标识变为True执行下面的代码print("标识1:", event.is_set())# 判断当前线程的状态logging.info("Good Job")defWorker(event:Event,count =10):logging.info("i am working for you")cups =[]while1:logging.info("make 1")time.sleep(0.5)cups.append(1)iflen(cups)>=10:print("标识2:",event.is_set())# 判断当前线程的状态event.set()# 通知,更改标识breaklogging.info("I finished my job,cups={}".format(cups))event = Event()
w = Thread(target=Worker,args=(event,))
b = Thread(target=boss,args=(event,))
w.start()
b.start()**************run_result************2023-03-2310:30:08,597-Thread-1-14700-i am working for you
2023-03-2310:30:08,597-Thread-1-14700-make 12023-03-2310:30:08,597-Thread-2-11076-i am boss waittinng for you
2023-03-2310:30:09,120-Thread-1-14700-make 12023-03-2310:30:09,630-Thread-1-14700-make 12023-03-2310:30:10,143-Thread-1-14700-make 12023-03-2310:30:10,648-Thread-1-14700-make 12023-03-2310:30:11,160-Thread-1-14700-make 12023-03-2310:30:11,666-Thread-1-14700-make 12023-03-2310:30:12,172-Thread-1-14700-make 12023-03-2310:30:12,679-Thread-1-14700-make 12023-03-2310:30:13,192-Thread-1-14700-make 1
标识2: False
标识1: True2023-03-2310:30:13,706-Thread-1-14700-I finished my job,cups=[1,1,1,1,1,1,1,1,1,1]2023-03-2310:30:13,706-Thread-2-11076-Good Job