eventfd(一)

函數原型:?創建的時候可以傳入一個計數器的初始值initval。 第二個參數flags在linux 2.6.26之前的版本是沒有使用的,必須初始化為0,在2.6.27之后的版本flag才被使用。

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

分析:

flags 可以是以下值的 OR 運算結果,用以改變 eventfd 的行為。

  • EFD_CLOEXEC (since Linux 2.6.27) 文件被設置成 O_CLOEXEC,創建子進程 (fork) 時不繼承父進程的文件描述符。
  • EFD_NONBLOCK (since Linux 2.6.27) 文件被設置成 O_NONBLOCK,執行 read / write 操作時,不會阻塞。
  • EFD_SEMAPHORE (since Linux 2.6.30) 提供類似信號量語義的 read 操作,簡單說就是計數值 count 遞減 1。

在 Linux 2.6.26 版本之前,沒有使用參數 flags,必須指定為 0。

操作方法

read: 讀取計數器中的值

  • 如果計數器中的值大于0
    1. 設置了EFD_SEMAPHORE標志位,則返回1,且計數器中的值也減去1。
    2. 沒有設置EFD_SEMAPHORE標志位,則返回計數器中的值,且計數器置0。
  • 如果計數器中的值為0
    1. 設置了EFD_NONBLOCK標志位就直接返回-1。
    2. 沒有設置EFD_NONBLOCK標志位就會一直阻塞直到計數器中的值大于0。

write: 向計數器中寫入值

  • 如果寫入值的和小于0xFFFFFFFFFFFFFFFE,則寫入成功
  • 如果寫入值的和大于0xFFFFFFFFFFFFFFFE
    1. 設置了EFD_NONBLOCK標志位就直接返回-1。
    2. 如果沒有設置EFD_NONBLOCK標志位,則會一直阻塞直到read操作執行

close: 關閉文件描述符,eventfd 對象引用計數減 1,若減為 0,則釋放 eventfd 對象資源。

測試代碼:

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>#define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char* argv[])
{int efd, j;uint64_t u;ssize_t s;if (argc < 2){fprintf(stderr, "Usage: %s <num>...\n", argv[0]);exit(EXIT_FAILURE);}efd = eventfd(0, 0);if (efd == -1)handle_error("eventfd");switch (fork()){case 0:for (j = 1; j < argc; j++){printf("Child writing %s to efd\n", argv[j]);u = atoi(argv[j]);s = write(efd, &u, sizeof(uint64_t));if (s != sizeof(uint64_t)){handle_error("write");}}printf("Child completed write loop\n");exit(EXIT_SUCCESS);default:sleep(2);printf("Parent about to read\n");s = read(efd, &u, sizeof(uint64_t));if (s != sizeof(uint64_t)){handle_error("read");}printf("Parent read %llu (0x%llx) from efd\n",(unsigned long long) u, (unsigned long long) u);exit(EXIT_SUCCESS);case -1:handle_error("fork");}
}

輸出結果:

?

?2. 測試代碼:

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>#define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char* argv[])
{int efd, j;uint64_t u;ssize_t s;if (argc < 2){fprintf(stderr, "Usage: %s <num>...\n", argv[0]);exit(EXIT_FAILURE);}efd = eventfd(0, EFD_NONBLOCK);if (efd == -1)handle_error("eventfd");switch (fork()){case 0:for (j = 1; j < argc; j++){printf("Child writing %s to efd\n", argv[j]);}printf("Child completed write loop\n");exit(EXIT_SUCCESS);default:sleep(2);printf("Parent about to read\n");s = read(efd, &u, sizeof(uint64_t));if (s != sizeof(uint64_t)){handle_error("read");}printf("Parent read %llu (0x%llx) from efd\n",(unsigned long long) u, (unsigned long long) u);exit(EXIT_SUCCESS);case -1:handle_error("fork");}
}

輸出結果:

?

3.?

#include <sys/eventfd.h>
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>#define handle_error(msg) do { perror(msg); exit(EXIT_FAILURE); } while (0)int main(int argc, char* argv[])
{int efd, j;uint64_t u;ssize_t s;if (argc < 2){fprintf(stderr, "Usage: %s <num>...\n", argv[0]);exit(EXIT_FAILURE);}efd = eventfd(0, EFD_SEMAPHORE);if (efd == -1)handle_error("eventfd");switch (fork()){case 0:for (j = 1; j < argc; j++){printf("Child writing %s to efd\n", argv[j]);u = atoi(argv[j]);s = write(efd, &u, sizeof(uint64_t));if (s != sizeof(uint64_t)){handle_error("write");}}printf("Child completed write loop\n");exit(EXIT_SUCCESS);default:sleep(2);printf("Parent about to read\n");s = read(efd, &u, sizeof(uint64_t));if (s != sizeof(uint64_t)){handle_error("read");}printf("Parent read %llu (0x%llx) from efd\n",(unsigned long long) u, (unsigned long long) u);exit(EXIT_SUCCESS);case -1:handle_error("fork");}
}

輸出結果:

參考資料:

  • Linux進程間通信-eventf
  • 通過實例來理解 eventfd 函數機制
  • ?

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/385185.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/385185.shtml
英文地址,請注明出處:http://en.pswp.cn/news/385185.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

gettimeofday

作用&#xff1a;需要打印代碼執行到某處的時間&#xff0c;或者需要計算程序執行的時間差&#xff08;精確到微妙級&#xff09;。這時會用到gettimeofday函數&#xff0c;它可以返回自1970-01-01 00:00:00到現在經歷的秒數。 #include <sys/time.h> int gettimeofday(…

02-線性結構2 一元多項式的乘法與加法運算 (20 分

設計函數分別求兩個一元多項式的乘積與和。 輸入格式: 輸入分2行&#xff0c;每行分別先給出多項式非零項的個數&#xff0c;再以指數遞降方式輸入一個多項式非零項系數和指數&#xff08;絕對值均為不超過1000的整數&#xff09;。數字間以空格分隔。 輸出格式: 輸出分2行&…

1066 圖像過濾 (15 分)

圖像過濾是把圖像中不重要的像素都染成背景色&#xff0c;使得重要部分被凸顯出來。現給定一幅黑白圖像&#xff0c;要求你將灰度值位于某指定區間內的所有像素顏色都用一種指定的顏色替換。 輸入格式&#xff1a; 輸入在第一行給出一幅圖像的分辨率&#xff0c;即兩個正整數 M…

從零實現一個http服務器

如果GET請求帶參數&#xff0c;那么一般是附加在請求的url后面&#xff0c;參數與參數之間使用&分割&#xff0c;例如請求http://www.hootina.org/index_2013.php?param1value1m2value2m3value3&#xff0c;我們看下這個請求組裝的的http協議包格式&#xff1a; GET /ind…

1068 萬綠叢中一點紅 (20 分)

對于計算機而言&#xff0c;顏色不過是像素點對應的一個 24 位的數值。現給定一幅分辨率為 MN 的畫&#xff0c;要求你找出萬綠叢中的一點紅&#xff0c;即有獨一無二顏色的那個像素點&#xff0c;并且該點的顏色與其周圍 8 個相鄰像素的顏色差充分大。 輸入格式&#xff1a; 輸…

《個人項目學習指引》

1. 從零實現一個http服務器

1069 微博轉發抽獎 (20 分)

小明 PAT 考了滿分&#xff0c;高興之余決定發起微博轉發抽獎活動&#xff0c;從轉發的網友中按順序每隔 N 個人就發出一個紅包。請你編寫程序幫助他確定中獎名單。 輸入格式&#xff1a; 輸入第一行給出三個正整數 M&#xff08;≤ 1000&#xff09;、N 和 S&#xff0c;分別是…

【1】TCP三次握手的第三次的 ack包丟失會怎樣?

面試題&#xff1a; 在 TCP 建立連接的三次握手連接階段&#xff0c;如果客戶端發送的第三個ACK包丟了&#xff0c;那么客戶端和服務端分別進行什么處理呢&#xff1f; 相信了解 tcp 協議的人&#xff0c;三次握手的過程肯定很了解了。第三次的 ack 包丟失就是說在 client 端…

1070 結繩 (25 分

給定一段一段的繩子&#xff0c;你需要把它們串成一條繩。每次串連的時候&#xff0c;是把兩段繩子對折&#xff0c;再如下圖所示套接在一起。這樣得到的繩子又被當成是另一段繩子&#xff0c;可以再次對折去跟另一段繩子串連。每次串連后&#xff0c;原來兩段繩子的長度就會減…

動態規劃目錄

序號題目1 70. 爬樓梯

1071 小賭怡情 (15 分)

常言道“小賭怡情”。這是一個很簡單的小游戲&#xff1a;首先由計算機給出第一個整數&#xff1b;然后玩家下注賭第二個整數將會比第一個數大還是小&#xff1b;玩家下注 t 個籌碼后&#xff0c;計算機給出第二個數。若玩家猜對了&#xff0c;則系統獎勵玩家 t 個籌碼&#xf…

53. 最大子序和

給定一個整數數組 nums &#xff0c;找到一個具有最大和的連續子數組&#xff08;子數組最少包含一個元素&#xff09;&#xff0c;返回其最大和。 示例: 輸入: [-2,1,-3,4,-1,2,1,-5,4], 輸出: 6 解釋: 連續子數組 [4,-1,2,1] 的和最大&#xff0c;為 6。 進階: 如果你已經實現…

1072 開學寄語 (20 分)

下圖是上海某校的新學期開學寄語&#xff1a;天將降大任于斯人也&#xff0c;必先刪其微博&#xff0c;卸其 QQ&#xff0c;封其電腦&#xff0c;奪其手機&#xff0c;收其 ipad&#xff0c;斷其 wifi&#xff0c;使其百無聊賴&#xff0c;然后&#xff0c;凈面、理發、整衣&am…

九大經典算法之插入排序、希爾排序

01 插入排序(Insertion Sort) 原理&#xff1a;每次選擇一個元素&#xff0c;并且將這個元素和整個數組中的所有元素進行比較&#xff0c;然后插入到合適的位置。 void insertion_sort(int arr[], int n) {int i,j;for (i 1; i < n; i) {int tmp arr[i];for (j i; j >…

九大經典算法之冒泡排序、快速排序

03 冒泡排序(Bubble Sort) 每次選擇兩個元素&#xff0c;按照需求進行交換&#xff08;比如需要升序排列的話&#xff0c;把較大的元素放在靠后一些的位置&#xff09;&#xff0c;循環 n 次&#xff08;n 為總元素個數&#xff09;&#xff0c;這樣小的元素會不斷 “冒泡” 到…

1073 多選題常見計分法 (20 分)

批改多選題是比較麻煩的事情&#xff0c;有很多不同的計分方法。有一種最常見的計分方法是&#xff1a;如果考生選擇了部分正確選項&#xff0c;并且沒有選擇任何錯誤選項&#xff0c;則得到 50% 分數&#xff1b;如果考生選擇了任何一個錯誤的選項&#xff0c;則不能得分。本題…

《二叉樹》目錄

序號題目標記 1 94. 二叉樹的中序遍歷 2 98. 驗證二叉搜索樹 3100. 相同的樹 4101. 對稱二叉樹 5 102. 二叉樹的層次遍歷 6 103. 二叉樹的鋸齒形層次遍歷 7104. 二叉樹的最大深度 8 105. 從前序與中序遍歷序列構造二叉樹 9106. 從中序與后序遍歷序列構造二叉樹 10107. 二叉…

1075 鏈表元素分類 (25 分)

給定一個單鏈表&#xff0c;請編寫程序將鏈表元素進行分類排列&#xff0c;使得所有負值元素都排在非負值元素的前面&#xff0c;而 [0, K] 區間內的元素都排在大于 K 的元素前面。但每一類內部元素的順序是不能改變的。例如&#xff1a;給定鏈表為 18→7→-4→0→5→-6→10→1…

C++ 面試(一)

1. 編譯器什么情況下&#xff0c;合成構造函數&#xff1f;[點擊鏈接(一)] 編譯器什么情況下&#xff0c;合成構造函數&#xff1f;

1074 宇宙無敵加法器 (20 分)

地球人習慣使用十進制數&#xff0c;并且默認一個數字的每一位都是十進制的。而在 PAT 星人開掛的世界里&#xff0c;每個數字的每一位都是不同進制的&#xff0c;這種神奇的數字稱為“PAT數”。每個 PAT 星人都必須熟記各位數字的進制表&#xff0c;例如“……0527”就表示最低…