io_add_watch 回调只触发一次?

Posted

技术标签:

【中文标题】io_add_watch 回调只触发一次?【英文标题】:io_add_watch callback only fires once? 【发布时间】:2016-04-20 06:10:52 【问题描述】:

我有一个命名管道,我想在数据可用时对其做出反应。我在 dbus 的上下文中这样做。对于设置,我有以下内容:

mainloop = glib.MainLoop()
fifo = os.open('_notify', os.O_RDWR)
glib.io_add_watch(fifo, glib.IO_IN, notifyLoop, service)
try:
    mainloop.run()
except KeyboardInterrupt:
    mainloop.quit()

所以在第 2 行和第 3 行中,我打开了命名管道,并在其中添加了一个手表。我的notifyLoop 回调:

def notifyLoop(fifo, cb_cond, service):
    dataStream = service.characteristics[0]
    all = os.read(fifo, 2048)
    print('all', all, 'cb_cond', cb_cond)
    payload, all = all[:20], all[20:]
    while payload:
        newValue = 'Value': [dbus.Byte(x) for x in payload]
        dataStream.PropertiesChanged(GATT_CHRC_IFACE, newValue, [])
        payload, all = all[:20], all[20:]

基本上,读取管道中的所有内容,然后分成大小为 20 的块并发出信号。问题是回调只触发一次,第一次。第一次,我看到打印,但是当我从另一个程序向管道写入更多数据时,什么也没有发生。我是否误解了io_add_watch 的工作方式?

这是我用来向命名管道写入两个独立内容的代码:

user@machine:/Directory# python3
Python 3.4.2 (default, Oct  8 2014, 14:38:51) 
[GCC 4.9.1] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import os
>>> fifo = os.open('_notify', os.O_RDWR)
>>> os.write(fifo, b'\xDE\xAD')
2
>>> os.write(fifo, b'\xBE\xEF')
2
>>> 

第一次写后,我明白了

all b'\xde\xad' cb_cond <flags G_IO_IN of type GIOCondition>

dbus 程序运行的位置。但是第二次写什么都没有。

【问题讨论】:

【参考方案1】:

您的回调必须返回True 才能根据pygtk2 reference 重新武装。这可用于通过显式返回 False 来进行单次触发回调。

此外,这不仅适用于GObject.io_add_watch 附加的回调,还适用于任何 GObject 回调。

【讨论】:

【参考方案2】:

通过反复试验,我确定我确实需要在每次回调事件结束时执行 glib.io_add_watch() 以继续重新启动它。

【讨论】:

以上是关于io_add_watch 回调只触发一次?的主要内容,如果未能解决你的问题,请参考以下文章

为啥间隔回调属于第一次渲染不能在每次间隔触发时向 React 发送更新指令(计数 +1)?

uni-app防抖和节流

如果回调函数没处理完,又产生了触发该回调函数的事件,怎么处理?

百度地图tilesloaded只触发一次

怎么让click事件在指定时间内只响应一次,jquery。

AJAX:仅触发错误回调