【发布时间】:2015-02-09 16:43:52
【问题描述】:
我有一个有 2 个线程的场景:
-
线程等待来自套接字的消息(嵌入在 C 库中 - 阻塞调用是“Barra.ricevi”)然后将元素放入队列中
-
等待从队列中获取元素并做某事的线程
示例代码
import Barra
import Queue
import threading
posQu = Queue.Queue(maxsize=0)
def threadCAN():
while True:
canMsg = Barra.ricevi("can0")
if canMsg[0] == 'ERR':
print (canMsg)
else:
print ("Enqueued message"), canMsg
posQu.put(canMsg)
thCan = threading.Thread(target = threadCAN)
thCan.daemon = True
thCan.start()
while True:
posMsg = posQu.get()
print ("Messagge from the queue"), posMsg
结果是每次来自套接字的新消息都会向队列中添加一个新元素,但是应该从队列中获取项目的主线程永远不会被唤醒。
输出如下:
排队的消息
排队的消息
排队的消息
排队的消息
我希望有:
排队的消息
队列中的消息
排队的消息
队列中的消息
解决这个问题的唯一方法是添加线缝:
posQu.join()
在等待来自socket的消息的线程结束时,一行:
posQu.task_done()
在主线程的末尾。
在这种情况下,从套接字接收到新消息后,线程将阻塞等待主线程处理入队的项目。
不幸的是,这不是我们想要的行为,因为我希望一个线程始终准备好从套接字获取消息,而不是等待另一个线程完成作业。
我做错了什么? 谢谢
安德鲁 (意大利)
【问题讨论】:
-
你能给我们一个独立的例子,不需要
Barra库吗?因为当我用只给它一个随机值的代码替换它时,它就像你想要的那样工作。所以我怀疑其他一些代码有问题,而不是这段代码。 -
由于 Pastebin 现在似乎已关闭,因此我的更改如下:将
import Barra替换为import random,将canMsg = barra.cicevi("can0")替换为canMsg = ['ERR'] if random.random() < .25 else [0, 1, 2],然后运行您的代码,您将看到队列和消息交错(通常在同一行)。 -
另外,CAN-bus真的和这个程序有关系吗? (也许你正在使用一个没有 pthread 的嵌入式 Linux 系统,所以它使用了虚拟线程?这可能可能导致这个问题......)
-
由于您在评论中给出的更改,我无法重现该问题。我收到有关入队和出队的消息。但是,它可能与一个奇怪的并且在您的情况下出现故障的调度有关。也许写入线程永远不会放弃处理器,因此系统(以及糟糕的调度机制)永远不会激活读取线程。您是否尝试过使用
Queue(1)而不是Queue(0)?这可能会使写入线程在尝试将第二条消息放入队列时立即进入睡眠状态。
标签: python linux multithreading queue can-bus