threading 模块
- threading.currentThread(): 返回当前的线程变量。
- threading.enumerate(): 返回一个包含正在运行的线程的list。正在运行指线程启动后、结束前,不包括启动前和终止后的线程。
- threading.activeCount(): 返回正在运行的线程数量,与len(threading.enumerate())有相同的结果。
Thread类提供了以下方法:
- run(): 用以表示线程活动的方法。
- start():启动线程活动。
- join([time]): 等待至线程中止。这阻塞调用线程直至线程的join() 方法被调用中止-正常退出或者抛出未处理的异常-或者是可选的超时发生。
- isAlive(): 返回线程是否活动的。
- getName(): 返回线程名。
- setName(): 设置线程名。
Thread构造器
在线程里,传递参数有三种方法:
- 使用元组传递
threading.Thread(target=方法名,args=(参数1,参数2, ...))
- 使用字典传递
threading.Thread(target=方法名, kwargs={"参数名": 参数1, "参数名": 参数2, ...})
- 混合使用元组和字典
threading.Thread(target=方法名,args=(参数1, 参数2, ...), kwargs={"参数名": 参数1,"参数名": 参数2, ...})
import threading
import time
def run(a, b, c):
print(a, b, c)
for i in range(3):
print("%s %s %d" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), threading.currentThread().name, i))
time.sleep(1)
threading.Thread(name="Thread-1", target=run, args=(1, 2, 3)).start()
threading.Thread(name="Thread-2", target=run, kwargs={"b": 2, "a": 1, "c": 3}).start()
threading.Thread(name="Thread-3", target=run, args=(1,), kwargs={"c": 3, "b": 2}).start()
继承线程类Thread
import threading
import time
class MyThread(threading.Thread):
def run(self) -> None:
print("%s running " % threading.currentThread().name)
for i in range(3):
print(
"%s %s %d" % (time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), threading.currentThread().name, i))
time.sleep(1)
thread1 = MyThread()
thread1.start()
thread2 = MyThread()
thread2.start()
thread1.join()
thread2.join()
print("%s the end..." % threading.currentThread().name)
线程同步锁
对于那些需要每次只允许一个线程操作的数据,可以将其操作放到 acquire 和 release 方法之间。
线程不安全示例:启动5个线程,每个线程循环1000000次,正常结果为1000000 * 5 = 5000000, 实际结果一般不是这个值。
import threading
import time
count = 0
class MyThread(threading.Thread):
def run(self) -> None:
global count
for i in range(1000000):
count += 1
print("%s end %s" % (threading.currentThread().name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
for _ in range(5):
thread = MyThread()
thread.start()
time.sleep(5)
print("%s the end... count=%d" % (threading.currentThread().name, count))
# Thread-1 end 2019-12-06 18:05:31
# Thread-2 end 2019-12-06 18:05:31
# Thread-3 end 2019-12-06 18:05:31
# Thread-4 end 2019-12-06 18:05:31
# Thread-5 end 2019-12-06 18:05:31
# MainThread the end... count=2203600
线程安全示例
Python通过锁机制来实现线程安全。通过threading.Lock()来获取锁,通过acquire()方法获取锁,通过release()释放锁。
import threading
import time
count = 0
threadLock = threading.Lock()
class MyThread(threading.Thread):
def run(self) -> None:
# 获取锁
threadLock.acquire()
global count
for i in range(1000000):
count += 1
print("%s end %s" % (threading.currentThread().name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
# 释放锁
threadLock.release()
for _ in range(5):
thread = MyThread()
thread.start()
time.sleep(5)
print("%s the end... count=%d" % (threading.currentThread().name, count))
# Thread-1 end 2019-12-06 18:10:20
# Thread-2 end 2019-12-06 18:10:20
# Thread-3 end 2019-12-06 18:10:20
# Thread-4 end 2019-12-06 18:10:20
# Thread-5 end 2019-12-06 18:10:20
# MainThread the end... count=5000000
上述示例acquire()和release()必须成对调用,开发中有可能写了acquire()而漏掉release(),Python提供了一个比较好用的语法with语法,可自动获取锁和自动释放锁。
import threading
import time
count = 0
threadLock = threading.Lock()
class MyThread(threading.Thread):
def run(self) -> None:
global count
with threadLock:
for i in range(1000000):
count += 1
print("%s end %s" % (threading.currentThread().name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
for _ in range(5):
thread = MyThread().start()
time.sleep(5)
print("%s the end... count=%d" % (threading.currentThread().name, count))
队列
- Queue(length): 指定队列的长度
- qsize() 返回队列的大小
- empty() 如果队列为空,返回True,反之False
- full() 如果队列满了,返回True,反之False
- get([block[, timeout]])获取队列,timeout等待时间
- put(item) 写入队列
- join() 实际上意味着等到队列为空,再执行别的操作
import queue
import threading
import time
exit_flag = 1
workQueue = queue.Queue(10)
class MyThread(threading.Thread):
def run(self) -> None:
print("%s end %s" % (threading.currentThread().name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())))
while exit_flag:
if not workQueue.empty():
data = workQueue.get()
print("%s %s %s" % (threading.currentThread().name, time.strftime("%Y-%m-%d %H:%M:%S", time.localtime()), data))
else:
break
time.sleep(1)
# 往队列中放内容
for item in range(10):
workQueue.put(item)
# 三个线程同时从队列中消费
threads = []
for i in range(3):
thread = MyThread()
thread.name = "Thread-" + str(i)
thread.start()
threads.append(thread)
# 等待队列清空
while not workQueue.empty():
pass
else:
exit_flag = 0
# 等待所有线程完成
for t in threads:
t.join()
print("主线程退出")
来源:CSDN
作者:vbirdbest
链接:https://blog.csdn.net/vbirdbest/article/details/103428927