Python研究学习--13--多线程编程(下)

版权声明:本文为博主原创文章,转载本站文章请注明作者和出处,请勿用于任何商业用途。 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"退出主线程"

猜你喜欢

转载自blog.csdn.net/wutianxu123/article/details/82528602