即使我阅读了所有内容,在 FIFO 上打开的 QSocketNotifier 也会继续触发
QSocketNotifier opened on a FIFO keeps firing even if I read everything
在我的代码中,我 open
一个 FIFO(使用 mkfifo
创建),然后我继续使用 QSocketNotifier
接收传入数据的通知,并在数据到达时读取它.
// create the FIFO
if(!mkfifo(SERIAL_FIFO, 0600)) {
// nonblocking open (even open itself would block until a first write)
in_fifo = ::open(SERIAL_FIFO, O_RDONLY | O_NONBLOCK);
if(in_fifo >= 0) {
// create notifier
in_fifo_notifier = new QSocketNotifier(in_fifo, QSocketNotifier::Read, this);
connect(&*in_fifo_notifier, &QSocketNotifier::activated,
this, [this](QSocketDescriptor /*socket*/, QSocketNotifier::Type /*type*/){
// copy all the available data
char buf[4096];
for(;;) {
ssize_t rl = ::read(in_fifo, buf, sizeof(buf));
if(rl <= 0) break;
::write(out_fd, buf, rl);
}
});
}
问题是,每当有人在管道的另一端写入时,信号就会不断激活(相关联的 100% CPU 使用率),即使每次我都读取所有数据。问题出在哪里?
最终,这只是 here 所描述问题的一个变体,因为 Qt 在后台使用 select
/epoll
机制来实现 QSocketNotifier
。打开 FIFO 为 O_RDWR
解决了这个问题。
在我的代码中,我 open
一个 FIFO(使用 mkfifo
创建),然后我继续使用 QSocketNotifier
接收传入数据的通知,并在数据到达时读取它.
// create the FIFO
if(!mkfifo(SERIAL_FIFO, 0600)) {
// nonblocking open (even open itself would block until a first write)
in_fifo = ::open(SERIAL_FIFO, O_RDONLY | O_NONBLOCK);
if(in_fifo >= 0) {
// create notifier
in_fifo_notifier = new QSocketNotifier(in_fifo, QSocketNotifier::Read, this);
connect(&*in_fifo_notifier, &QSocketNotifier::activated,
this, [this](QSocketDescriptor /*socket*/, QSocketNotifier::Type /*type*/){
// copy all the available data
char buf[4096];
for(;;) {
ssize_t rl = ::read(in_fifo, buf, sizeof(buf));
if(rl <= 0) break;
::write(out_fd, buf, rl);
}
});
}
问题是,每当有人在管道的另一端写入时,信号就会不断激活(相关联的 100% CPU 使用率),即使每次我都读取所有数据。问题出在哪里?
最终,这只是 here 所描述问题的一个变体,因为 Qt 在后台使用 select
/epoll
机制来实现 QSocketNotifier
。打开 FIFO 为 O_RDWR
解决了这个问题。