我打開一個命名管道(FIFO由mkfifo創建)與非阻塞標誌(開(... O_NONBLOCK)),然後開始輪詢(民意調查(...))。到現在爲止還挺好。 然後在命令行我做了幾個投票()的命名管道與POLLHUP不斷返回,並立即
echo 123 > /tmp/fifo
管他們都讀出如預期(至少我希望這是他們應該如何正常工作)。
我的問題是,第一回波後,POLLHUP設置,它被卡住,調查從這一點立即返回。
我如何明確 /擺脫POLLHUP?
它開始我發瘋:(
是管道的另一端得到關閉(後,這是先前打開的),所以就成了半封閉,但我最終仍然是開放的,充滿活力,我喜歡這種方式。這不是死了,我還可以通過管道接收新的回聲,它只是民調呼聲POLLHUP的河流(我沒有在事件首位甚至要求,但民意調查可以只標記他們無論如何[人民調查:「revents可以包括任何事件中指定的那些,或其中一個值POLLERR,POLLHUP」]),並且因此非常無用。因爲我仍然希望得到關於它的新數據的通知。
我不想關閉它,因爲它不是一次性使用管道,我喜歡重複使用相同的東西而不是將它們扔掉......除此之外,我沒有管道名稱了,只有我有文件描述符(從fd獲取文件名看起來像一個婊子...我也谷歌搜索...)
我仍然相信Linux的力量,並且必須有更好的(更高的性能/比賽條件安全)的方式來做到這一點。
這是我看過,但沒有幫助解決問題。
- http://www.greenend.org.uk/rjk/tech/poll.html - 民意調查似乎是一個 滾泥的樂趣確實負載...
- socket: constantly getting POLLHUP on half-close - 不,我不希望關閉它,它不是一個插座,這是一個管( 必須首先在閱讀器端打開)
- How to use the poll C function to watch named pipes in Linux? - 這是我的問題,但如何解決它?當我打開管它是作爲 多半閉(實際上是半開的:)作爲以後有人在上面寫東西 之後他們關閉了他們的目的,但我只得到 POLLHUP風暴半閉那些沒有半開的人(因此有一個 差異)。
在我絕望我試圖做這樣的事情,甚至(這並沒有幫助):
int newfd = dup(fds[i].fd);
close(fds[i].fd);
dup2(newfd, fds[i].fd);
close(newfd);
任何想法?我在做一些完全錯誤的事情嗎? (我現在總是可以回去試圖週期性地讀取所有管道(這實際上是工作的),現在這不是延遲關鍵,但是我不知道如果它是什麼,我會怎麼做......)
這裏有一些代碼重現我的問題(這不是我想要建立的生產代碼,有明顯超過1管,我想輪詢...)
#include <stdio.h>
#include <sys/types.h> // mkfifo
#include <sys/stat.h> // mkfifo
#include <unistd.h>
#include <fcntl.h>
#include <errno.h>
#include <string.h>
#include <poll.h>
int main(int argc, char **argv) {
char* pipename = "/tmp/fifo";
mkfifo(pipename, S_IWUSR | S_IRUSR | S_IRGRP);
int fd = open(pipename, O_RDONLY | O_NONBLOCK); /// O_ASYNC, O_SYNC
struct pollfd fds[1];
fds[0].fd = fd;
fds[0].events = POLLIN;
fds[0].revents = 0;
while (1) {
int res = poll(fds, 1, 1000);
if (res<0) { perror("poll"); return 1; }
if (res==0) { printf(".\n"); continue; }
printf("Poll [%d]: 0x%04x on %d\n", 0, fds[0].revents, fds[0].fd);
char buff[512];
int count = (int)read(fds[0].fd, buff, (size_t)(sizeof(buff)-1));
if (count>=0) {
buff[count] = 0;
printf("Pipe read %d bytes: '%s'\n", count, buff);
usleep(1000*100); /// cpu protector sleep for POLLHUP :)
}
}
return 0;
}
注意事項:
我在Linux(lubuntu)平臺(x64)上使用gcc(4.6.3)。但最終我想交叉編譯它以實現嵌入式目標。
我敢肯定,我一定是錯過了一些信息撕成小塊出來,所以問了......
解決方案/解決方法:通過mark4o建議
- 解決方法1是打開的管道與
O_RDWR
而不是O_RDONLY
。這樣你不會得到恆定的POLLHUP
-s(當然你不會得到任何女巫可能是一個問題)。此外,讀者需要對管道進行寫入許可(在某些情況下可能沒有)。
感謝您提供額外的質量信息。我知道管道原子操作緩衝區的限制,這不是一個問題,我也沒有打算使用1個管道與多個作家,但很多單獨的管道。用O_RDWR打開輸入管道的工作,所以我接受這個答案:)謝謝你的想法。 –