zoukankan      html  css  js  c++  java
  • threading多线程的生产者消费者模型

    理解此篇请先看http://www.cnblogs.com/haiyan123/p/7445584.html

    """多线程下生产者消费者模型。定义:在同一进程,同一主线程下,
    采用多线程完成多个任务的同时,各自数据保持干净整洁。即、花最少的时间
    完成最多的任务"""
    import threading
    import random
    import time
    # 初始化金额
    gMoney = 1000
    #
    gLock = threading.Lock()
    # 最大生产次数
    gTotalTimes = 10
    # 计数器
    gTimes = 0
    
    
    class Producer(threading.Thread):
        """生产者"""
        def run(self):
            global gMoney      # 引用全局变量需先声明
            global gTimes
            while True:
                # 生产随机金额
                money = random.randint(100, 1000)
                # 加锁
                gLock.acquire()
                # 判断生产次数
                if gTimes >= gTotalTimes:
                    gLock.release()
                    break
                # 金额增加
                gMoney += money
                print("%s生产了%d元钱,剩余%d元钱" % ("小黑", money, gMoney))
                # 生产完成计数器加一
                gTimes += 1
                # 释放锁
                gLock.release()
                time.sleep(1)
    
    
    class Consumer(threading.Thread):
        """消费者"""
        def run(self):
            global gMoney
            while True:
                # 消费随机金额
                money = random.randint(100, 1000)
                # 加锁
                gLock.acquire()
                # 判断剩余金额大于消费数继续消费
                if gMoney >= money:
                    gMoney -= money
                    print("%s消费了%d元钱,剩余%d元钱" % ("小胖子", money, gMoney))
                else:
                    # 判断生产次数大于最大生产数停止消费释放锁
                    if gTimes >= gTotalTimes:
                        gLock.release()
                        break
                    print("%s消费者准备消费%d元钱,剩余%d元钱,不足" % ("小白", money, gMoney))
                # 释放锁
                gLock.release()
                time.sleep(1)
    
    
    def main():
        for x in range(5):
            t = Producer(name="生产者线程%s" % x)
            t.start()
    
        for i in range(3):
            t = Consumer(name="消费者线程%s" % i)
            t.start()
    
    
    if __name__ == '__main__':
        main()
    View Code

     线程执行效率优化之condition

    """confition采用事件通知,避免while True:条件下空数据后反复循环。"""
    import threading
    import random
    import time
    # 初始化金额
    gMoney = 1000
    #
    gCondition = threading.Condition()    #
    # 最大生产次数
    gTotalTimes = 10
    # 计数器
    gTimes = 0
    
    
    class Producer(threading.Thread):
        """生产者"""
        def run(self):
            global gMoney      # 引用全局变量需先声明
            global gTimes
            while True:
                # 生产随机金额
                money = random.randint(100, 1000)
                # 加锁
                gCondition.acquire()
                # 判断生产次数
                if gTimes >= gTotalTimes:
                    gCondition.release()
                    break
                # 金额增加
                gMoney += money
                print("%s生产了%d元钱,剩余%d元钱" % ("小黑", money, gMoney))
                # 生产完成计数器加一
                gTimes += 1
                # 通知所有正在等待的线程
                gCondition.notify_all()
                # 释放锁
                gCondition.release()
                time.sleep(1)
    
    
    class Consumer(threading.Thread):
        """消费者"""
        def run(self):
            global gMoney
            while True:
                # 消费随机金额
                money = random.randint(100, 1000)
                # 加锁
                gCondition.acquire()
                while gMoney < money:
                    if gTimes >= gTotalTimes:
                        gCondition.release()
                        return
                    print("%s准备消费%d元钱,剩余%d元钱,不足" % ("小胖子", money, gMoney))
                    # 钱不够就夯住,不会去反复上锁解锁,等待被唤醒
                    gCondition.wait()
                gMoney -= money
                print("%s消费了%d元钱,剩余%d元钱" % ("小胖子", money, gMoney))
                gCondition.release()
                time.sleep(1)
    
    
    def main():
        for i in range(3):
            t = Consumer(name="消费者线程%s" % i)
            t.start()
    
        for x in range(5):
            t = Producer(name="生产者线程%s" % x)
            t.start()
    
    
    if __name__ == '__main__':
        main()
    View Code

     线程安全队列之queue

    """queue线程安全队列,先进先出"""
    from queue import Queue
    import threading
    import time
    
    q = Queue(2)    # 生成q队列对象,参数表示最大队列数(限制用)
    q.put(1)        # 推送值到q队列中
    q.put(2)
    print(q.qsize())          # 获取队列中队列个数
    print(q.full())           # 判断队列是否满了,满为True,反之False
    print(q.empty())          # 队列为空返回True,反之False
    print(q.get())            # 从q队列中获取值
    # block=True默认
    q.get(block=True)         # 获取不到值默认夯住
    q.put(1)                   # 满了默认夯住
    
    
    def set_value(q):
        index = 0
        while True:
            q.put(index)
            index += 1
            time.sleep(3)
    
    
    def get_value(q):
        while True:
            print(q.get())
    
    
    def main():
        q = Queue(4)
        # 传递q给调用函数
        t1 = threading.Thread(target=set_value, args=[q])
        t2 = threading.Thread(target=get_value, args=[q])
        t1.start()
        t2.start()
    
    
    if __name__ == '__main__':
        main()
    View Code
  • 相关阅读:
    项目经理成长之路-初入职场(二)
    项目经理成长之路-我的大学(一)
    别了郑州,2020再出发
    RPC协议实践入门
    Spark学习进度11-Spark Streaming&Structured Streaming
    使用Python自动填写问卷星(pyppeteer反爬虫版)
    All mirror URLs are not using ftp, http[s] or file.
    2018蓝桥杯A组省赛A,B,C,D
    Spark学习进度10-DS&DF基础操作
    SparkSQL学习进度9-SQL实战案例
  • 原文地址:https://www.cnblogs.com/Guishuzhe/p/9844956.html
Copyright © 2011-2022 走看看