import threading # 加载线程库import time
defworker():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,9):
time.sleep(1)print("welcome to study python!")defworker_1():# 自定义线程函数,启动线程后要调用的方法for i inrange(0,5):
time.sleep(1)print("welcome to study threading……!")
t = threading.Thread(target=worker)# 对线程库中的类进行实例化,指定线程调用的函数
t.start()#启动线程,线程启动之后,不杀死线程的情况下# 要将目标函数执行完才能结束
t1 = threading.Thread(target=worker_1)
t1.start()# 并发运行,有两个函数,启动两个线程print(t.is_alive())# 判断线程是否是活动的
代码解析:
通过threading.Thread创建一个线程对象,target是目标函数
线程启动调用start方法
并发调用多个函数,就需要启动两个线程,分别对应不同的函数,已达到并发的效果
线程的退出和传参
python中,没有提供线程退出的方法,线程会在下面情况下退出
线程函数内语句执行完毕
线程函数中抛出未处理的异常
python中的线程没有优先级,没有线程组的概念,也不能被销毁,停止,挂起,因此也就没有恢复和中断
线程的传参和函数的传参没有区别,其本质上就是函数传参,实参传元祖,关键字参数传字典
threading的属性和方法
current_thread:返回当前线程的对象
main_thread:返回主线程的对象
active_count:当前处于alive状态的线程个数
enumerate:返回所有或者的线程列表
包括已经终止的线程和未开始的线程
get_ident:返回当前线程的ID,非0 整数
import threading # 加载线程库import time
defworker():# 自定义线程函数,启动线程后要调用的方法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 time
defworker():# 自定义线程函数,启动线程后要调用的方法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())
time.sleep(10)print(t.name)print(t.ident)print(t.is_alive())**********************run_result*******************
Thread-111240True
welcome to study python!
welcome to study python!
welcome to study python!
Thread-111240False
Thread-1
lala
False
import threading # 加载线程库import time
global_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 x
for 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 time
FORMAT ="%(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()# 通知,更改标识break
logging.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
import logging
import threading
import time
FORMAT ="%(asctime)s-%(threadName)s-%(thread)d-%(message)s"
logging.basicConfig(format=FORMAT,level=logging.INFO)defworker(tasks):for task in tasks:
time.sleep(0.2)if task.lock.acquire(False):# 获取到锁,则返回True,没有则是False
logging.info("{} {} begin to start".format(threading.current_thread(),task.name))
time.sleep(3)
task.lock.release()# 选取适当的时机释放锁else:
logging.info("{} {} begin to working".format(threading.current_thread(), task.name))classTask:def__init__(self,name):
self.name = name
self.lock = threading.Lock()# 构造10个任务,构造10个对象,即10把锁
tasks =[Task("task={}".format(x))for x inrange(10)]# 启动5个线程,即启动5把锁,一个线程已经拿到锁,另外一个线程就拿不到了# 就走worker中的elsefor i inrange(5):
threading.Thread(target=worker,name="worker={}".format(i),args=(tasks,)).start()