多线程之间的通讯

方式一、使用全局变量的方式进行线程之间通讯

  • 1、创建两个线程,一个是获取详情页面的url,一个请求该url

      import threading
      import random
      import time
    
      detail_url_list = []
    
      def get_detail_html():
          """
          请求文章详情页面方法
          :return:
          """
          while True:
              global detail_url_list
              if len(detail_url_list):
                  url = detail_url_list.pop()
                  print('开始获取文章详情页数据:{}'.format(url))
                  time.sleep(random.randrange(5))
                  print('结束获取文章详情页数据')
    
      def get_detail_url():
          """
          获取文章详情页面的url
          :return:
          """
          global detail_url_list
          print('开始获取url')
          time.sleep(random.randrange(5))
          for i in range(20):
              detail_url_list.append('https://www.baidu.com/{}'.format(i))
          print('结束获取url')
    
      if __name__ == "__main__":
          t1 = threading.Thread(target=get_detail_url)
          t2 = threading.Thread(target=get_detail_html)
          t1.start()
          t1.join()
          t2.start()
          t2.join()
    
  • 2、使用锁的方式定义一个生产者与消费者

    import time
    import random
    import threading
    
    # 定义仓库里面多少包子
    gBum = 100
    # 总共生产多少次
    gTotalTimes = 10
    # 定义当前的
    gTimes = 0
    # 创建一把锁
    gLock = threading.Lock()
    
    class Producer(threading.Thread):
        """
        定义一个生产者,来生产包子,在生产过程中上锁不销售
        """
    
        def run(self):
            global gBum
            global gTotalTimes
            global gTimes
            while True:
                gLock.acquire()
                bum = random.randint(0, 10)
                # 当生产大于指定的次数的时候退出线程
                if gTimes >= gTotalTimes:
                    gLock.release()
                    break
                gBum += bum
                gTimes += 1
                gLock.release()
                print('{0}生产了:{1}个包子,还剩余:{2}个包子'.format(threading.current_thread(), bum, gBum))
                # 休眠时间,可以理解为生产包子需要时间
                time.sleep(random.randrange(3))
    
    class Consumer(threading.Thread):
        """
        定义一个消费者的类,来消费包子
        """
    
        def run(self):
            global gBum
            global gTotalTimes
            global gTimes
            while True:
                bum = random.randint(0, 10)
                gLock.acquire()
                if gBum > bum:
                    gBum -= bum
                    print("{0}在消费包子,消费了{1}个,还剩余{2}".format(threading.current_thread(), bum, gBum))
                else:
                    # 当包子不足的时候且当前数大于总共生产次数的时候退出线程
                    if gTimes >= gTotalTimes:
                        print("{0}在消费包子,消费了{1}个,但是包子数量不够,还剩余{2}".format(threading.current_thread(), bum, gBum))
                        gLock.release()
                        break
                gLock.release()
                # 休眠时间,可以理解为消费包子需要时间
                time.sleep(random.randrange(3))
    
    if __name__ == '__main__':
        # # 启动八个消费者线程
        for x in range(8):
            t = Consumer(name='消费者线程%d' % x)
            t.start()
    
        # 启动三个生产者
        for x in range(3):
            t = Producer(name='生产者%d' % x)
            t.start()
    

方式二、使用队列(queue)

  • 1、队列的基本认识

    队列是一种数据类型,与python中的list数据类型差不多,用来存放多个数据的,只是python为队列新增了一些自己的方法。

  • 2、队列的几种形式

    • 1.先进先出队列 class queue.Queue(maxsize)
    • 2.先进后出队列 class queue.LifoQueue(maxsize)
    • 3.优先级队列 class queue.PriorityQueue(maxsize)
  • 3、队列中常用的方法

    • 1.put(val): 在队列尾部插入元素
    • 2.get(): 从队列头部删除一个元素,并返回该元素
    • 3.qsize(): 返回队列的大小
    • 4.empty(): 判断队列是否为空
    • 5.full(): 判断队列是否已经满
    • 6.task_done(): 完成一项工作后,发送一个信号
    • 7.join(): 等待队列为空的时候再执行
  • 4、基本的使用

    import queue
    
    if __name__ == "__main__":
        q = queue.Queue(10)
        q.put('hello word')
        q.put(12)
        q.put({'name': '张三', 'gender': '男'})
        print(q.get())
        print(q.get())
    

results matching ""

    No results matching ""