鱼C论坛

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

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

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

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

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

x
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 ("开启线程:" + self.name)
        process_data(self.name, self.q)
        print ("退出线程:" + self.name)

def process_data(threadName, q):
    while not exitFlag:
        queueLock.acquire()
        if not workQueue.empty():
            data = q.get()
            queueLock.release()
            print ("%s processing %s" % (threadName, data))
        else:
            queueLock.release()
        time.sleep(1)

threadList = ["Thread-1", "Thread-2", "Thread-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)
queueLock.release()

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

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

# 等待所有线程完成
for t in threads:
    t.join()
print ("退出主线程")

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

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

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

使用道具 举报

发表于 2020-1-8 02:54:08 | 显示全部楼层
# 等待队列清空
while not workQueue.empty():
    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()两个方法才会增加队列中的内容
# 等待队列清空
while not workQueue.empty():
    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-6-17 13:50

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

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