__thread模块
基础知识 开启一个新线程
_thread.start_new_thread(function, args[, kwargs])
例如
import _thread,time
def child(tid):
print('Hello from thread', tid)
def parent():
i = 0
_thread.start_new_thread(child, (i,))
time.sleep(3)
print('hhe')
if __name__ == '__main__':
parent()
>>>
Hello from thread 0
hhe #(3s之后)
###
本例中载入_thread模块和创建线程并调用。
_thread.start_new_thread调用本身立即返回一个没有用的值,它派生出来的线程在其运行函数返回后安静的退出。用_thread模块时,大多数系统平台上整个程序退出时随之退出。上例中如果把time.sleep(3)的代码注释,则新线程的输出可能不成功。主线程就结束了,分线程也会随之结束
import \_thread, time
def action(i):
print(i ** 32)
class Power:
def __init__(self, i):
self.i = i
def action(self):
print(self.i ** 32)
_thread.start_new_thread(action, (2,)) #绑定简单函数
_thread.start_new_thread((lambda: action(2)), ()) #绑定lambda表达式
obj = Power(2)
_thread.start_new_thread(obj.action, ()) #绑定方法对象
time.sleep(2)
print('Main thread exiting.')
###
在线程中对实例对象的状态做出任何改变,对于所有其他线程都是可见的
同时运行多个线程
import _thread as thread, time
def counter(myId, count): # 线程中运行的程序
for i in range(count):
time.sleep(1) # 模拟耗时操作
print('[%s] => %s' % (myId, i))
for i in range(5): # 开启5个线程
thread.start_new_thread(counter, (i, 5)) # 每个线程中循环5次
time.sleep(6)
print('Main thread exiting.')
线程所的概念
避免多个线程同时争夺同意资源而必须采用线程锁。
基础知识
mutex = _thread.allocate_lock() 创建锁
mutex.acquire()使用锁
.....操作要处理的对象
mutext.release() 释放锁
示例代码
import \_thread as thread, time
def counter(myId, count):
for i in range(count):
time.sleep(1)
mutex.acquire() #用锁
print('[%s] => %s' % (myId, i))
mutex.release() #解锁
mutex = thread.allocate_lock() # 创建一个全局锁
for i in range(5):
thread.start_new_thread(counter, (i, 5))
time.sleep(6)
print('Main thread exiting.')
可以根据线程锁的状态来判断某个线程有没有完成耗时操作
import _thread as thread
stdoutmutex = thread.allocate_lock()
exitmutexes = [thread.allocate_lock() for i in range(10)]
#exitmutexes = [False]*10
def counter(myId, count):
for i in range(count):
stdoutmutex.acquire()
print('[%s] => %s' % (myId, i))
stdoutmutex.release()
exitmutexes[myId].acquire() # 标记myId线程完成任务
#exitmutexes[myId] = True
for i in range(10):
thread.start_new_thread(counter, (i, 100))
for mutex in exitmutexes: #实时检测状态锁的状态。一旦全部锁住表示所有线程都完成任务。则循环完成
while not mutex.locked(): pass
#while False in exitmutexes:pass
print('Main thread exiting.')
threading
threading模块在内部使用_thread模块来实现代表线程的对象以及常用同步化工具的功能
import threading
class Mythread(threading.Thread): # 继承Thread的子类
def __init__(self, myId, count, mutex):
self.myId = myId
self.count = count
self.mutex = mutex # 传递来的线程锁
threading.Thread.__init__(self)
def run(self): # 真正线程做的工作
for i in range(self.count): # 同步化 with语句线程锁
with self.mutex:
print('[%s] => %s' % (self.myId, i))
stdoutmutex = threading.Lock() #线程锁
threads = []
for i in range(10):
thread = Mythread(i, 100, stdoutmutex)
thread.start() # 开始运行新的线程
threads.append(thread)
for thread in threads:
thread.join() # 等待线程结束 join
print('Main thread exiting.')
threading模块里的线程用Thread对象实现,通过提供定义线程的run方法来进行定制Python类Mythread,当我们创建一个Mythread类实例并调用其start方法时,run方法将在新的线程中执行。
Thread.join()方法可等待线程退出,采用这个方法避免主线程在子线程之前退出。
其他编程方法 可以直接利用Thread的默认run方法直接调用传给构造器的target参数的可调用对象aciton,args参数为传递给action的参数
threading.Thread(group=None, target=None, name=None, args=(), kwargs={}, *, daemon=None)
import threading
def action(i):print(i**32)
thread = threading.Thread(target=action,arg=(2,))
thread.start() #执行action
queue模块
queue模块提供一个标准的队列数据结构---一个先进先出的Python对象列表。队列对象自动有线程锁获取和释放操作控制,在任意给定时间只有一个线程能够修改队列
numconsumers = 2
numproducers = 4
nummessages = 4
import _thread as thread, queue, time
safeprint = thread.allocate_lock()
dataQueue = queue.Queue() # 共享全局变量,没有限制大小 可以传参限制大小
def producer(idnum, dataqueue):
for msgnum in range(nummessages):
time.sleep(idnum)
dataqueue.put('[producer id=%d, count=%d]' % (idnum, msgnum)) #放入队列
def consumer(idnum, dataqueue):
while True:
time.sleep(0.1)
try:
data = dataqueue.get(block=False) #从队列里取值,如果队列为空者引发异常
except queue.Empty:
pass
else:
with safeprint: #线程锁
print('consumer', idnum, 'got =>', data)
if __name__ == '__main__':
for i in range(numconsumers):
thread.start_new_thread(consumer, (i, dataQueue))
for i in range(numproducers):
thread.start_new_thread(producer, (i, dataQueue))
time.sleep(((numproducers-1) * nummessages) + 1) #保证主线程最后退出
print('Main thread exit.')