日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux 新api eventfd(转)

發布時間:2025/4/9 linux 23 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux 新api eventfd(转) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

轉自http://www.cppblog.com/peija/archive/2010/10/07/128941.html

eventfd 在內核版本,2.6.22以后有效。查看內核版本可以用命令 uname -r 。

1 #include <sys/eventfd.h> 2 int eventfd(unsigned int initval, int flags);

這個函數會創建一個 事件對象 (eventfd object), 用來實現,進程(線程)間 的 等待/通知(wait/notify) 機制. 內核會為這個對象維護一個64位的計數器(uint64_t)。
?并且使用第一個參數(initval)初始化這個計數器。調用這個函數就會返回一個新的文件描述符(event object)。2.6.27版本開始可以按位設置第二個參數(flags)。
有如下的一些宏可以使用:

EFD_NONBLOCK , 功能同open(2) 的O_NONBLOCK,設置對象為非阻塞狀態,如果沒有設置這個狀態的話,read(2)讀eventfd,并且計數器的值為0 就一直堵塞在read調用當中,要是設置了這個標志, 就會返回一個 EAGAIN 錯誤(errno = EAGAIN)。效果也如同 額外調用select(2)達到的效果。

EFD_CLOEXEC 我的理解是,這個標識被設置的話,調用exec后會自動關閉文件描述符,防止泄漏。

如果是2.6.26或之前版本的內核,flags 必須設置為0。

創建這個對象后,可以對其做如下操作。

write 將緩沖區寫入的8字節整形值加到內核計數器上。

read 讀取8字節值, 并把計數器重設為0. 如果調用read的時候計數器為0, 要是eventfd是阻塞的, read就一直阻塞在這里,否則就得到 一個EAGAIN錯誤。
如果buffer的長度小于8那么read會失敗, 錯誤代碼被設置成 EINVAL。

poll select epoll

close 當不需要eventfd的時候可以調用close關閉, 當這個對象的所有句柄都被關閉的時候,內核會釋放資源。 為什么不是close就直接釋放呢, 如果調用fork 創建
進程的時候會復制這個句柄到新的進程,并繼承所有的狀態。?


下面是一個例子

1 #include <sys/eventfd.h> 2 #include <unistd.h> 3 #include <stdio.h> 4 #include <stdint.h> 5 #include <stdlib.h> 6 #include <errno.h> 7 8 #define handle_error(msg) \ 9 do { perror(msg); exit(1); } while (0) 10 11 int main( int argc, char **argv ) 12 { 13 uint64_t u; 14 ssize_t s; 15 int j; 16 if ( argc < 2 ) { 17 fprintf(stderr, "input <num> in command argument"); 18 exit(1); 19 } 20 21 int efd; 22 if ( (efd = eventfd(0, EFD_NONBLOCK)) == -1 ) 23 handle_error("eventfd failed"); 24 25 26 switch (fork()) { 27 case 0: 28 for( j = 1; j < argc; j ++ ) { 29 printf("Child writing %s to efd\n", argv[j] ); 30 31 u = strtoull(argv[j], NULL, 0); /* analogesly atoi */ 32 s = write(efd, &u, sizeof(uint64_t)); /* append u to counter */ 33 if ( s != sizeof(uint64_t) ) 34 handle_error("write efd failed"); 35 36 } 37 printf("child completed write loop\n"); 38 39 exit(0); 40 default: 41 sleep (2); 42 43 printf("parent about to read\n"); 44 s = read(efd, &u, sizeof(uint64_t)); 45 if ( s != sizeof(uint64_t) ) { 46 if (errno = EAGAIN) { 47 printf("Parent read value %d\n", s); 48 return 1; 49 } 50 handle_error("parent read failed"); 51 } 52 printf("parent read %d , %llu (0x%llx) from efd\n", 53 s, (unsigned long long)u, (unsigned long long) u); 54 exit(0); 55 56 case -1: 57 handle_error("fork "); 58 } 59 return 0; 60 }

這個API還是很有用的, 當你想要編寫并發型服務器的時候,aventfd 可以完美取代 pipe去通知(喚醒)其他的進程(線程)。比如經典的異步IO reactor/selector?
應用場景,去喚醒select的調用。他的緩沖區處理非常方便, 規定只有8字節。

?

轉載于:https://www.cnblogs.com/minuse/p/7472795.html

總結

以上是生活随笔為你收集整理的Linux 新api eventfd(转)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。