python3内置两个thread模块:
- _thread模块
- threading模块
推荐使用threading模块
1.数据共享,线程同步
如果多个线程共同对某个数据修改,则可能产生混乱结果,为了保证数据的正确性,需要对多个线程进行同步。使用 Thread 对象的 Lock 或 Rlock 可以实现简单的线程同步,这两个对象都有 acquire 方法和 release 方法,对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。
示例代码:
#!/usr/bin/env python3
import time, threading
var = 0
lock = threading.Lock()
def change_it(n):
# 设为全局共享变量
global var
var = var + n
var = var - n
def run_thread(n):
for i in range(3):
# 先要获取锁:
lock.acquire()
change_it(n)
# 改完了一定要释放锁:
lock.release()
t1 = threading.Thread(target=run_thread, args=(5,)) # 逗号不能省!
t2 = threading.Thread(target=run_thread, args=(8,))
t1.start()
t2.start()
t1.join()
t2.join()
2.线程阻塞
threading.Event为事件处理的机制,全局定义了一个“Flag”:
- 如果“Flag”值为 False,那么当程序执行 event.wait 方法时就会阻塞;
- 如果“Flag”值为True,那么执行event.wait 方法时便不再阻塞。
- clear:将“Flag”设置为False
- set:将“Flag”设置为True
用 threading.Event 实现线程间通信,*可以使一个线程等待其他线程的通知,我们把这个Event传递到线程对象中,Event默认内置了一个标志,初始值为False。一旦该线程通过wait()方法进入等待状态,直到另一个线程调用该Event的set()方法将内置标志设置为True时,该Event会通知所有等待状态的线程恢复运行。
示例代码:
import threading, time
import random
def light():
if not event.isSet(): #初始化evet的flag为真
event.set() #wait就不阻塞 #绿灯状态
count = 0
while True:
if count < 10:
print('\033[42;1m---green light on---\033[0m')
elif count < 13:
print('\033[43;1m---yellow light on---\033[0m')
elif count < 20:
if event.isSet():
event.clear()
print('\033[41;1m---red light on---\033[0m')
else:
count = 0
event.set() #打开绿灯
time.sleep(1)
count += 1
def car(n):
while 1:
time.sleep(random.randrange(3, 10))
#print(event.isSet())
if event.isSet():
print("car [%s] is running..." % n)
else:
print('car [%s] is waiting for the red light...' % n)
event.wait() #红灯状态下调用wait方法阻塞,汽车等待状态
if __name__ == '__main__':
car_list = ['BMW', 'AUDI', 'SANTANA']
event = threading.Event()
Light = threading.Thread(target=light)
Light.start()
for i in car_list:
t = threading.Thread(target=car, args=(i,))
t.start()
3. threading.active_count()
返回当前存活的线程对象的数量;通过计算len(threading.enumerate())长度而来
import threading, time
def run():
thread = threading.current_thread()
print('%s is running...'% thread.getName()) #返回线程名称
time.sleep(10) #休眠10S方便统计存活线程数量
if __name__ == '__main__':
#print('The current number of threads is: %s' % threading.active_count())
for i in range(10):
print('The current number of threads is: %s' % threading.active_count()) #返回当前存活线程数量
thread_alive = threading.Thread(target=run, name='Thread-***%s***' % i)
thread_alive.start()
thread_alive.join()
print('\n%s thread is done...'% threading.current_thread().getName())
4. threading.get_ident()
返回线程pid
import threading, time
def run(n):
print('-'*30)
print("Pid is :%s" % threading.get_ident()) # 返回线程pid
if __name__ == '__main__':
threading.main_thread().setName('Chengd---python') #自定义线程名
for i in range(3):
thread_alive = threading.Thread(target=run, args=(i,))
thread_alive.start()
thread_alive.join()
print('\n%s thread is done...'% threading.current_thread().getName()) #获取线程名
其他用法可以参考