鱼C论坛

 找回密码
 立即注册
查看: 1325|回复: 8

[已解决]queue.Queue类的一个小问题

[复制链接]
发表于 2020-1-7 23:55:18 | 显示全部楼层 |阅读模式

马上注册,结交更多好友,享用更多功能^_^

您需要 登录 才可以下载或查看,没有账号?立即注册

x
  1. import queue
  2. import threading
  3. import time

  4. exitFlag = 0

  5. class myThread (threading.Thread):
  6.     def __init__(self, threadID, name, q):
  7.         threading.Thread.__init__(self)
  8.         self.threadID = threadID
  9.         self.name = name
  10.         self.q = q
  11.     def run(self):
  12.         print ("开启线程:" + self.name)
  13.         process_data(self.name, self.q)
  14.         print ("退出线程:" + self.name)

  15. def process_data(threadName, q):
  16.     while not exitFlag:
  17.         queueLock.acquire()
  18.         if not workQueue.empty():
  19.             data = q.get()
  20.             queueLock.release()
  21.             print ("%s processing %s" % (threadName, data))
  22.         else:
  23.             queueLock.release()
  24.         time.sleep(1)

  25. threadList = ["Thread-1", "Thread-2", "Thread-3"]
  26. nameList = ["One", "Two", "Three", "Four", "Five"]
  27. queueLock = threading.Lock()
  28. workQueue = queue.Queue(10)
  29. threads = []
  30. threadID = 1

  31. # 创建新线程
  32. for tName in threadList:
  33.     thread = myThread(threadID, tName, workQueue)
  34.     thread.start()
  35.     threads.append(thread)
  36.     threadID += 1

  37. # 填充队列
  38. queueLock.acquire()
  39. for word in nameList:
  40.     workQueue.put(word)
  41. queueLock.release()

  42. # 等待队列清空
  43. while not workQueue.empty():
  44.     pass

  45. # 通知线程是时候退出
  46. exitFlag = 1

  47. # 等待所有线程完成
  48. for t in threads:
  49.     t.join()
  50. print ("退出主线程")
复制代码


其中,等待队列清空的while语句,这样的写法,如果队列为空,岂不是死循环了吗,不理解这样的写法,希望大神可以解惑。
最佳答案
2020-1-8 23:41:36
介左来了 发表于 2020-1-8 22:37
按照我的理解,对于队列只有get() 和 put()两个方法才会增加队列中的内容

当程序执行到此处时,while ...

肯定啊,啥是多线程?? 你以为程序堵塞在这里,其他的不运行了?其他线程肯定在消耗队列任务呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复

使用道具 举报

发表于 2020-1-8 02:54:08 | 显示全部楼层
  1. # 等待队列清空
  2. while not workQueue.empty():
  3.     pass
复制代码


队列为空,这里就过了,有任务才堵塞在这里,别搞反了。   empty  这个函数在起作用,没有任务才返回True
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-8 06:40:31 From FishC Mobile | 显示全部楼层
Stubborn 发表于 2020-1-8 02:54
队列为空,这里就过了,有任务才堵塞在这里,别搞反了。   empty  这个函数在起作用,没有任务才返回Tr ...

写的时候没注意,如果队列非空时,是不是一直卡在这边?
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-8 16:07:00 | 显示全部楼层
介左来了 发表于 2020-1-8 06:40
写的时候没注意,如果队列非空时,是不是一直卡在这边?

肯定拉,不卡这里就退出任务了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-8 20:58:08 | 显示全部楼层
Stubborn 发表于 2020-1-8 16:07
肯定拉,不卡这里就退出任务了

所以我就比较不理解,如果语句执行到这边时非空,那岂不是程序到这边永远都跳不出while循环了吗?此处的意义是什么啊
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-8 21:00:11 | 显示全部楼层
介左来了 发表于 2020-1-8 20:58
所以我就比较不理解,如果语句执行到这边时非空,那岂不是程序到这边永远都跳不出while循环了吗?此处的 ...


目的就是堵塞啊,让队列的任务执行完在退出呀~不然 程序就退出

想不通吗?有任务堵塞,程序不退出,没任务不堵塞,过这里,然后就结束线程了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-8 22:37:02 | 显示全部楼层
Stubborn 发表于 2020-1-8 21:00
目的就是堵塞啊,让队列的任务执行完在退出呀~不然 程序就退出

想不通吗?有任务堵塞,程序不退出, ...

按照我的理解,对于队列只有get() 和 put()两个方法才会增加队列中的内容
  1. # 等待队列清空
  2. while not workQueue.empty():
  3.     pass
复制代码

当程序执行到此处时,while语句体是pass,加入队列是非空状态,语句体中又没有get()方法,那岂不是语句体一直处于非空状态,程序执行到此处时就陷入了无限循环中?

写到此处,突然意识到,while语句执行的同时,多个线程同时也在对队列中的内容进行get()吧,所以队列空了之后,while后面的标志位才会翻转,这样理解对吧。
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

发表于 2020-1-8 23:41:36 | 显示全部楼层    本楼为最佳答案   
介左来了 发表于 2020-1-8 22:37
按照我的理解,对于队列只有get() 和 put()两个方法才会增加队列中的内容

当程序执行到此处时,while ...

肯定啊,啥是多线程?? 你以为程序堵塞在这里,其他的不运行了?其他线程肯定在消耗队列任务呀
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

 楼主| 发表于 2020-1-9 13:52:22 From FishC Mobile | 显示全部楼层
谢谢,理解了
想知道小甲鱼最近在做啥?请访问 -> ilovefishc.com
回复 支持 反对

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|手机版|Archiver|鱼C工作室 ( 粤ICP备18085999号-1 | 粤公网安备 44051102000585号)

GMT+8, 2024-5-26 06:22

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表