线程
线程的创建
1、使用threading模块创建,通过指定target和args参数,创建线程
2、使用Thread类,重写run方法
3、使用线程池
使用threading模块创建线程
import threading
import time
def sum(num):
sum = 0
for i in range(num):
sum = sum + i
print(sum)
## 创建线程
t1 = threading.Thread(target=sum,args=(10,))
t2 = threading.Thread(target=sum,args=(8,))
## 激活线程
t1.start()
t2.start()
注意,start()
方法仅仅是将当前线程任务加到cpu执行任务列表中,具体执行还是要等cpu的分配。
使用Thread类,重写run方法
class MyThread(threading.Thread):
def __init__(self,num):
self.num = num
super().__init__()
def run(self):
sum = 0
for i in range(self.num):
sum = sum + i
print(sum)
t1 = MyThread(10)
t2 = MyThread(9)
t1.start()
t2.start()
当需要创建很多个执行相同方法的线程对象时,建议使用继承Thread类,重写run方法。
注意:run()
方法才是真正执行任务函数的方法。
线程池
pool = ThreadPoolExecutor(3)
a = pool.submit(func,args)
线程的相关操作
1、threading.active_count()
:计算处于活跃状态的线程数量。
2、threading.enumerate()
:返回一个list,包含正在运行的线程。
3、threading.get_ident()
:获得线程的标志,不同的线程标志不同,且唯一。
4、threading.main_thread()
:返回执行解释器的线程,主线程.
5、threading.current_thread()
:获得当前执行的线程。
6、start()
:激活线程,就绪状态。
7、run()
:运行线程内容。
8、join()
:抢占时间片
9、name
:给线程设置名字。
10、ident
:线程标志 属性。
11、is_alive()
:判断是否存活的线程。
12、daemon()
:设置是否是守护线程。
join()示例
def mission():
print("===修路ing===")
time.sleep(1)
print("修路完毕")
t = threading.Thread(target=mission)
t.start()
print("想要过马路")
print("路修好了,过马路")
输出结果为
===修路ing===
想要过马路
路修好了,过马路
修路完毕
加入join()之后
:
def mission():
print("===修路ing===")
time.sleep(1)
print("修路完毕")
t = threading.Thread(target=mission)
t.start()
print("想要过马路")
t.join()
print("路修好了,过马路")
输出结果为
===修路ing===
想要过马路
修路完毕
路修好了,过马路
加入join之后,线程t抢占时间片,也就是说,必须等线程t执行完毕之后才可以继续执行后面的代码。
线程的同步
在同一个进程下面,共享很多线程,线程之间对于资源上是共享,共享会引发线程不安全的问题。
ticket = 100
def buy_tick():
global ticket
while ticket > 0:
t = threading.current_thread()
print("{}抢到了第{}张票".format(t.name,ticket))
ticket -= 1
t1 = threading.Thread(target=buy_tick)
t1.name = "张三"
t2 = threading.Thread(target=buy_tick)
t2.name = "李四"
t3 = threading.Thread(target=buy_tick)
t3.name = "王五"
t1.start()
t2.start()
t3.start()
运行截图如下:
我们可以看出,这里同时抢了第97张票,也就是说共享资源被多个线程访问可能会造成安全问题。可以使用线程锁来解决这个问题。
threading中提供了锁的方法
lock = threading.Lock() lock.acquire() # 获取锁 lock.release() # 释放锁
lock = threading.Lock()
ticket = 100
def buy_tick():
global ticket
while True:
try:
lock.acquire()
if ticket > 0:
t = threading.current_thread()
time.sleep(0.2)
print("{}抢到了第{}张票".format(t.name,ticket))
ticket -= 1
else :
break
finally:
lock.release()
t1 = threading.Thread(target=buy_tick)
t1.name = "张三"
t2 = threading.Thread(target=buy_tick)
t2.name = "李四"
t3 = threading.Thread(target=buy_tick)
t3.name = "王五"
t1.start()
t2.start()
t3.start()
死锁
定义:当两个或多个线程同时拥有自己的资源,而此时,互相等待获得对方资源,这时候会导致死锁。