eventfd_write() 第二个参数=0 不起作用?
eventfd_write() with 2nd argument=0 doesn't work?
当使用第二个参数 =0 调用 eventfd_write() 时,epoll_wait() 永远不会 returns,但当参数设置为 1 时。epoll_wait( ) returns.
这是我重现的方式:
./错误 0
从来没有returns。
./bug 1
它returns.
代码如下:
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <assert.h>
#include <cstdlib>
#include <iostream>
int value = 0;
int efd = 0;
void* start(void* p) {
std::cout << __PRETTY_FUNCTION__ << ": going to sleep for 5 sec" << std::endl;
sleep(5);
std::cout << __PRETTY_FUNCTION__ << ": going to call eventfd_write() with value=" << value << std::endl;
const int rc = eventfd_write(efd, value);
assert(0 == rc);
return NULL;
}
int main(int argc, char** argv) {
const int epFD = epoll_create1(0);
assert(-1 != epFD);
efd = eventfd(0, 0);
assert(-1 != efd);
struct epoll_event event;
event.data.fd = efd;
event.events = EPOLLIN;
epoll_ctl(epFD, EPOLL_CTL_ADD, efd, &event);
value = strtoul(argv[1], NULL, 10);
const uint32_t nEvents = 2;
struct epoll_event events[nEvents];
pthread_t threadID;
const int rc = pthread_create(&threadID, NULL, &start, NULL);
assert(0 == rc);
sleep(1);
std::cout << __PRETTY_FUNCTION__ << ": going to wait for event" << std::endl;
int n = epoll_wait(epFD, events, nEvents, -1);
assert(n > 0);
std::cout << "okay" << std::endl;
return 0;
}
以下是我的编译方式:
g++ -Wall bug.cpp -o bug -O3 -lpthread
这是我的 glibc 版本:
$ rpm -qa | grep glibc
glibc-common-2.12-1.107.el6.x86_64
glibc-static-2.12-1.107.el6.x86_64
glibc-headers-2.12-1.107.el6.x86_64
glibc-2.12-1.107.el6.x86_64
glibc-devel-2.12-1.107.el6.x86_64
这是我的 g++ 版本:
$ g++ --version
g++ (GCC) 4.6.2 20111027 (Red Hat 4.6.2-1)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
有什么想法吗?
简答:
阅读 documentation
更长的答案:
"A write(2) call adds the 8-byte integer value supplied in its buffer to the counter"
"The file descriptor is readable (the select(2) readfds argument; the poll(2) POLLIN flag) if the counter has a value greater than 0."
因此,写入 0 不会向计数器添加任何内容,值 0 意味着正在等待的文件描述符尚未就绪。任何非零值都应该有效(保留的 0xffffffff 除外)。
当使用第二个参数 =0 调用 eventfd_write() 时,epoll_wait() 永远不会 returns,但当参数设置为 1 时。epoll_wait( ) returns.
这是我重现的方式: ./错误 0
从来没有returns。
./bug 1
它returns.
代码如下:
#include <sys/epoll.h>
#include <sys/eventfd.h>
#include <assert.h>
#include <cstdlib>
#include <iostream>
int value = 0;
int efd = 0;
void* start(void* p) {
std::cout << __PRETTY_FUNCTION__ << ": going to sleep for 5 sec" << std::endl;
sleep(5);
std::cout << __PRETTY_FUNCTION__ << ": going to call eventfd_write() with value=" << value << std::endl;
const int rc = eventfd_write(efd, value);
assert(0 == rc);
return NULL;
}
int main(int argc, char** argv) {
const int epFD = epoll_create1(0);
assert(-1 != epFD);
efd = eventfd(0, 0);
assert(-1 != efd);
struct epoll_event event;
event.data.fd = efd;
event.events = EPOLLIN;
epoll_ctl(epFD, EPOLL_CTL_ADD, efd, &event);
value = strtoul(argv[1], NULL, 10);
const uint32_t nEvents = 2;
struct epoll_event events[nEvents];
pthread_t threadID;
const int rc = pthread_create(&threadID, NULL, &start, NULL);
assert(0 == rc);
sleep(1);
std::cout << __PRETTY_FUNCTION__ << ": going to wait for event" << std::endl;
int n = epoll_wait(epFD, events, nEvents, -1);
assert(n > 0);
std::cout << "okay" << std::endl;
return 0;
}
以下是我的编译方式:
g++ -Wall bug.cpp -o bug -O3 -lpthread
这是我的 glibc 版本:
$ rpm -qa | grep glibc
glibc-common-2.12-1.107.el6.x86_64
glibc-static-2.12-1.107.el6.x86_64
glibc-headers-2.12-1.107.el6.x86_64
glibc-2.12-1.107.el6.x86_64
glibc-devel-2.12-1.107.el6.x86_64
这是我的 g++ 版本:
$ g++ --version
g++ (GCC) 4.6.2 20111027 (Red Hat 4.6.2-1)
Copyright (C) 2011 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
有什么想法吗?
简答: 阅读 documentation
更长的答案: "A write(2) call adds the 8-byte integer value supplied in its buffer to the counter"
"The file descriptor is readable (the select(2) readfds argument; the poll(2) POLLIN flag) if the counter has a value greater than 0."
因此,写入 0 不会向计数器添加任何内容,值 0 意味着正在等待的文件描述符尚未就绪。任何非零值都应该有效(保留的 0xffffffff 除外)。