eventfd是linux 2.6.22後系統提供的一個輕量級的進程間通訊的系統調用,eventfd經過一個進程間共享的64位計數器完成進程間通訊,這個計數器由在linux內核空間維護,用戶能夠經過調用write方法向內核空間寫入一個64位的值,也能夠調用read方法讀取這個值。linux
建立一個eventfd對象,或者說打開一個eventfd的文件,相似普通文件的open操做。
該對象是一個內核維護的無符號的64位整型計數器。初始化爲initval的值。ios
#include <sys/eventfd.h> int eventfd(unsigned int initval, int flags);
flags能夠如下三個標誌位的OR結果:微信
EFD_CLOEXEC
: fork子進程時不繼承,對於多線程的程序設上這個值不會有錯的。EFD_NONBLOCK
: 文件會被設置成O_NONBLOCK,讀操做不阻塞。若不設置,一直阻塞直到計數器中的值大於0。EFD_SEMAPHORE
: 支持 semophore 語義的read,每次讀操做,計數器的值自減1。讀取計數器中的值。網絡
typedef uint64_t eventfd_t; int eventfd_read(int fd, eventfd_t *value);
EFD_SEMAPHORE
標誌位,則返回1,且計數器中的值也減去1。EFD_SEMAPHORE
標誌位,則返回計數器中的值,且計數器置0。EFD_NONBLOCK
標誌位就直接返回-1。EFD_NONBLOCK
標誌位就會一直阻塞直到計數器中的值大於0。向計數器中寫入值。多線程
int eventfd_write(int fd, eventfd_t value);
若是寫入值的和小於0xFFFFFFFFFFFFFFFE,則寫入成功post
若是寫入值的和大於0xFFFFFFFFFFFFFFFEui
EFD_NONBLOCK
標誌位就直接返回-1。EFD_NONBLOCK
標誌位,則會一直阻塞直到read操做執行#include <unistd.h> int close(int fd);
示例1-一讀一寫:線程
#include <sys/eventfd.h> #include <unistd.h> #include <iostream> int main() { int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); eventfd_write(efd, 2); eventfd_t count; eventfd_read(efd, &count); std::cout << count << std::endl; close(efd); }
上述程序主要作了以下事情:code
示例2-多讀多寫:
#include <sys/eventfd.h> #include <unistd.h> #include <iostream> int main() { int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); eventfd_write(efd, 2); // 寫入2,計數器爲2 eventfd_write(efd, 3); // 寫入3, 計數器爲2 + 3 = 5 eventfd_write(efd, 4); // 寫入3, 計數器爲5 + 4 = 9 eventfd_t count; int read_result = eventfd_read(efd, &count); std::cout << "read_result=" << read_result << std::endl; // 0 std::cout << "count=" << count << std::endl; // count = 9 read_result = eventfd_read(efd, &count); std::cout << "read_result=" << read_result << std::endl; // -1,返回失敗 std::cout << "count=" << count << std::endl; // count = 9,爲原來的值 close(efd); }
示例3-EFD_SEMAPHORE標誌位的做用:
#include <sys/eventfd.h> #include <unistd.h> #include <iostream> int main() { int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC | EFD_SEMAPHORE); eventfd_write(efd, 2); // 寫入2,計數器爲2 eventfd_t count; int read_result = eventfd_read(efd, &count); // count = 1,計數器自減1,爲1 std::cout << "read_result=" << read_result << std::endl; // 0 std::cout << "count=" << count << std::endl; // 1 read_result = eventfd_read(efd, &count); // count = 1,計數器自減1,爲0 std::cout << "read_result=" << read_result << std::endl; // 0 std::cout << "count=" << count << std::endl; // 1 read_result = eventfd_read(efd, &count); // 讀取失敗 std::cout << "read_result=" << read_result << std::endl; // -1,讀取失敗 std::cout << "count=" << count << std::endl; // 1 close(efd); }
能夠看到設置了EFD_SEMAPHORE後,每次讀取到的值都是1,且read後計數器也遞減1。
NFVschool,關注最前沿的網絡技術。