版权声明:本文为博主原创文章,转载本站文章请注明作者和出处,请勿用于任何商业用途。 https://blog.csdn.net/wutianxu123/article/details/82528602
12.3 线程同步
代码实例:
# -*- coding: UTF-8 -*-
from atexit import register #导入相关模块
from random import randrange
from time import sleep,ctime
from threading import BoundedSemaphore,Lock,Thread
#BoundedSemaphore信号量。实质为计数器,向外分配计数-1,向内回收计数+1
lock=Lock() #锁
max=5 #定义一个最大值常量
tangguopan=BoundedSemaphore(max) #糖果盘。实质是一个计数器
def tianjia(): #添加糖果时调用的函数
lock.acquire() #获得锁,成功获得锁定后返回True
print u"补充糖果"
try:
tangguopan.release() #释放糖果盘(计数器)
except ValueError: #超过最大库存数时
print u"满了,不要了"
else:
print u"补充好了"
lock.release() #释放锁
def maidiao(): #卖掉糖果时调用的函数
lock.acquire() #获得锁,成功获得锁定后返回True
print u"卖糖果"
if tangguopan.acquire(False): #获得糖果盘(计数器)。如果有就卖,卖光就跳转
print u"卖掉了"
else:
print u"老铁,没东西可卖了"
lock.release() #释放锁
def producer(loops): #第一个循环
for i in xrange(loops):
tianjia() #调用添加糖果函数
sleep(randrange(3)) #睡眠。时间为3秒内的一个随机数,这也是为什么每次结果不一样的主要原因
def consumer(loops): #第二个循环
for i in xrange(loops):
maidiao() #调用卖掉函数
sleep(randrange(3)) #睡眠。时间为3秒内的一个随机数
def main(): #定义主函数
print u"开始时间为:",ctime()
nloops=randrange(2,6) #2-6之间去随机数
print u"装满糖果机需要%d个糖果" % max
Thread(target=consumer,args=(randrange(nloops,nloops+max+2),)).start() #创建线程1并让其开始,主要是用来添加糖果
Thread(target=producer,args=(nloops,)).start() #创建线程2并让其开始。主要是用来卖掉糖果
def _atexit(): #退出函数的注册
print u"都已完成:",ctime()
if __name__=="__main__":
main()
代码实例:
# -*- coding: UTF-8 -*-
import threading #导入模块
import time
class myThread (threading.Thread): #定义类,继承父类
def __init__(self, threadID, name, counter): #定义类内的初始函数(__init__函数),用于接收传参
threading.Thread.__init__(self) #父类(Thread)中的初始函数的声明
self.threadID = threadID #将函数参数转换为类内全局变量
self.name = name
self.counter = counter
def run(self): #定义表示线程活动的函数
print u"\n开始:" + self.name
threadLock.acquire() #获得锁,成功获得锁定后返回True
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 -= 1 #counter=counter-1
threadLock = threading.Lock() #变量赋值
threads = [] #定义了一个空列表。列表名为threads
thread1 = myThread(1, "xiancheng-1", 1) #创建新线程。同时对类进行实例化,传入实参
thread2 = myThread(2, "xiancheng-2", 2)
thread1.start() #开启新线程
thread2.start()
threads.append(thread1) #添加线程到线程列表
threads.append(thread2)
for t in threads: #join()是一个等待所有线程完成后才执行的东西
t.join()
print u"退出主线程"
12.4 线程优先级队列
代码实例:
# -*- coding: UTF-8 -*-
from random import randint #导入模块
from time import sleep
from Queue import Queue
from myThread import MyThread
def shengchan(queue): #参数是用来接收数据的形参
print u"生产面包:",queue.put('xxx',1) #形参的put函数。将一个值放入队列的队尾中
print u"面包尺寸大小:",queue.qsize() #返回队列的大小
def xiaofei(queue): #参数是用来接收数据的形参
sleep(1) #为了让消费延迟运行,不然会同时运行
val=queue.get(1) #将一个值从队列中去取出
print u"吃掉面包:",queue.qsize() #返回队列的大小
def shengchanxian(queue,loops): #两个参数是用来接收数据的形参
for i in range(loops):
shengchan(queue) #调用生产函数
sleep(randint(1,3)) #睡眠。随机取1-3秒,注意必须是两个数之间
def xiaofeixian(queue,loops): #两个参数是用来接收数据的形参
for i in range(loops):
xiaofei(queue) #调用消费函数
sleep(randint(2,5)) #睡眠。随机取2-5秒,注意必须是两个数之间
funcs=[shengchanxian,xiaofeixian] #设置派生的线程总数
nfuncs=range(len(funcs)) #设置执行的线程总数
def main():
nloops=randint(2,5) #取2-5之间的随机数
q=Queue(32)
threads=[] #新建列表。列表名为队列"threads"
for i in nfuncs:
t=MyThread(funcs[i],(q,nloops),funcs[i].__name__) #创建线程时使用子类(MyThread是模块导入类)
threads.append(t)
for i in nfuncs:
threads[i].start() #开始执行线程
for i in nfuncs:
threads[i].join() #在上面程序执行完之前保持阻塞,所以这句话总是最后出现的
print u"不吃了,吃饱了!"
if __name__=="__main__":
main()
代码实例:
# -*- coding: UTF-8 -*-
import Queue #导入模块
import threading
import time
exitFlag = 0 #定义变量
class 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 u"\n开始:" + self.name+u" 具体时间:"+time.ctime(time.time())
process_data(self.name, self.q) #调用函数。传入实参
print u"\n退出:" + self.name+u" 具体时间:"+time.ctime(time.time())
def process_data(threadName, q): #定义函数,接收实参
while not exitFlag: #此处始终未真
time.sleep(0.1) #睡眠0.1秒可以使代码延迟从而格式不混乱
queueLock.acquire() #获得锁
if not workQueue.empty():
data = q.get()
queueLock.release() #释放锁
print u"\n%s 赋值为 %s" % (threadName, data)
else:
queueLock.release() #释放锁
threadList = ["xiancheng-1", "xiancheng-2", "xiancheng-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) #形参的put函数。将一个值放入队列的队尾中
queueLock.release()
while not workQueue.empty(): #等待队列清空
pass
exitFlag = 1 #通知线程是时候退出
for t in threads: #等待所有线程完成
t.join()
print u"退出主线程"