- ·上一篇文章:Python3 SMTP发送邮件
- ·下一篇文章:Python3 XML 解析
Python3 多线程
:一个列表里所有元素都是0,线程"set"从后向前把所有元素改成1,而线程"print"负责从前往后读取列表并打印。那么,可能线程"set"开始改的时候,线程"print"便来打印列表了,输出就成了一半0一半1,这就是数据的不同步。为了避免这种情况,引入了锁的概念。锁有两种状态——锁定和未锁定。每当一个线程比如"set"要访问共享数据时,必须先获得锁定;如果已经有别的线程比如"print"获得锁定了,那么就让线程"set"暂停,也就是同步阻塞;等到线程"print"访问完毕,释放锁以后,再让线程"set"继续。经过这样的处理,打印列表时要么全部输出0,要么全部输出1,不会再出现一半0一半1的尴尬场面。实例:
#!/usr/bin/python3import threadingimport timeclass myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self):
print ("开启线程: " + self.name)
# 获取锁,用于线程同步 threadLock.acquire() print_time(self.name, self.counter, 3)
# 释放锁,开启下一个线程 threadLock.release()def print_time(threadName, delay, counter):
while counter:
time.sleep(delay) print ("%s:
%s" % (threadName, time.ctime(time.time()))) counter -= 1threadLock = threading.Lock()threads = []
# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)
# 开启新线程thread1.start()thread2.start()
# 添加线程到线程列表threads.append(thread1)threads.append(thread2)
# 等待所有线程完成for t in threads:
t.join()print ("退出主线程")执行以上程序,输出结果为:开启线程: Thread-1开启线程: Thread-2Thread-1:
Wed Apr 6 11:
52:
57 2016Thread-1:
Wed Apr 6 11:
52:
58 2016Thread-1:
Wed Apr 6 11:
52:
59 2016Thread-2:
Wed Apr 6 11:
53:
01 2016Thread-2:
Wed Apr 6 11:
53:
03 2016Thread-2:
Wed Apr 6 11:
53:
05 2016退出主线程线程优先级队列( Queue)Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之FalseQueue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 Queue.get_nowait() 相当Queue.get(False)Queue.put(item) 写入队列,timeout等待时间 Queue.put_nowait(item) 相当Queue.put(item, False)Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join() 实际上意味着等到队列为空,再执行别的操作实例:
#!/usr/bin/python3import queueimport threadingimport timeexitFlag = 0class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self):
print ("开启线程:" + self.name) process_data(self.name, self.q) print ("退出线程:" + self.name)def process_data(threadName, q):
while not exitFlag:
queueLock.acquire() if not workQueue.empty():
data = q.get() queueLock.release() print ("%s processing %s" % (threadName, data)) else:
queueLock.release() time.sleep(1)threadList = ["Thread-1", "Thread-2", "Thread-3"]nameList = ["One", "Two", "Three", "Four", "Five"]queueLock = threading.Lock()workQueue = queue.Queue(10)threads = []threadID = 1
# 创建新线程for tName in threadList:
thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1
# 填充队列queueLock.acquire()for word in nameList:
workQueue.put(word)queueLock.release()
# 等待队列清空while not workQueue.empty():
pass
# 通知线程是时候退出exitFlag = 1
# 等待所有线程完成for t in threads:
t.join()print ("退出主线程")以上程序执行结果:开启线程:Thread-1开启线程:Thread-2开启线程:Thread-3Thread-3 processing OneThread-1 processing TwoThread-2 processing ThreeThread-3 processing FourThread-1 processing Five退出线程:Thread-3退出线程:Thread-2退出线程:Thread-1退出主线程
#!/usr/bin/python3import threadingimport timeclass myThread (threading.Thread):
def __init__(self, threadID, name, counter):
threading.Thread.__init__(self) self.threadID = threadID self.name = name self.counter = counter def run(self):
print ("开启线程: " + self.name)
# 获取锁,用于线程同步 threadLock.acquire() print_time(self.name, self.counter, 3)
# 释放锁,开启下一个线程 threadLock.release()def print_time(threadName, delay, counter):
while counter:
time.sleep(delay) print ("%s:
%s" % (threadName, time.ctime(time.time()))) counter -= 1threadLock = threading.Lock()threads = []
# 创建新线程thread1 = myThread(1, "Thread-1", 1)thread2 = myThread(2, "Thread-2", 2)
# 开启新线程thread1.start()thread2.start()
# 添加线程到线程列表threads.append(thread1)threads.append(thread2)
# 等待所有线程完成for t in threads:
t.join()print ("退出主线程")执行以上程序,输出结果为:开启线程: Thread-1开启线程: Thread-2Thread-1:
Wed Apr 6 11:
52:
57 2016Thread-1:
Wed Apr 6 11:
52:
58 2016Thread-1:
Wed Apr 6 11:
52:
59 2016Thread-2:
Wed Apr 6 11:
53:
01 2016Thread-2:
Wed Apr 6 11:
53:
03 2016Thread-2:
Wed Apr 6 11:
53:
05 2016退出主线程线程优先级队列( Queue)Python 的 Queue 模块中提供了同步的、线程安全的队列类,包括FIFO(先入先出)队列Queue,LIFO(后入先出)队列LifoQueue,和优先级队列 PriorityQueue。这些队列都实现了锁原语,能够在多线程中直接使用,可以使用队列来实现线程间的同步。Queue 模块中的常用方法:
Queue.qsize() 返回队列的大小 Queue.empty() 如果队列为空,返回True,反之False Queue.full() 如果队列满了,返回True,反之FalseQueue.full 与 maxsize 大小对应 Queue.get([block[, timeout]])获取队列,timeout等待时间 Queue.get_nowait() 相当Queue.get(False)Queue.put(item) 写入队列,timeout等待时间 Queue.put_nowait(item) 相当Queue.put(item, False)Queue.task_done() 在完成一项工作之后,Queue.task_done()函数向任务已经完成的队列发送一个信号Queue.join() 实际上意味着等到队列为空,再执行别的操作实例:
#!/usr/bin/python3import queueimport threadingimport timeexitFlag = 0class myThread (threading.Thread):
def __init__(self, threadID, name, q):
threading.Thread.__init__(self) self.threadID = threadID self.name = name self.q = q def run(self):
print ("开启线程:" + self.name) process_data(self.name, self.q) print ("退出线程:" + self.name)def process_data(threadName, q):
while not exitFlag:
queueLock.acquire() if not workQueue.empty():
data = q.get() queueLock.release() print ("%s processing %s" % (threadName, data)) else:
queueLock.release() time.sleep(1)threadList = ["Thread-1", "Thread-2", "Thread-3"]nameList = ["One", "Two", "Three", "Four", "Five"]queueLock = threading.Lock()workQueue = queue.Queue(10)threads = []threadID = 1
# 创建新线程for tName in threadList:
thread = myThread(threadID, tName, workQueue) thread.start() threads.append(thread) threadID += 1
# 填充队列queueLock.acquire()for word in nameList:
workQueue.put(word)queueLock.release()
# 等待队列清空while not workQueue.empty():
pass
# 通知线程是时候退出exitFlag = 1
# 等待所有线程完成for t in threads:
t.join()print ("退出主线程")以上程序执行结果:开启线程:Thread-1开启线程:Thread-2开启线程:Thread-3Thread-3 processing OneThread-1 processing TwoThread-2 processing ThreeThread-3 processing FourThread-1 processing Five退出线程:Thread-3退出线程:Thread-2退出线程:Thread-1退出主线程
Python3 多线程