#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/select.h>
#include <fcntl.h>
#include <unistd.h>
int main(int argc, char* argv[]){
if(argc < 2){
puts("err argv");
return -1;
}
int r_fd = open(argv[1], O_RDWR);
int w_fd = open(argv[1], O_RDWR);
fd_set r_set;
fd_set w_set;
char w_buf[4096];
char r_buf[2048];
int read_count = 0,write_count = 0;
while(1){
FD_ZERO(&r_set);
FD_ZERO(&w_set);
FD_SET(r_fd, &r_set);
FD_SET(w_fd, &w_set);
int ret = select(w_fd + 1, &r_set, &w_set, NULL, NULL);
if(FD_ISSET(r_fd, &r_set)){
read(r_fd, r_buf, sizeof(r_buf));
printf("read count:%d\n", read_count++);
}
if(FD_ISSET(w_fd, &w_set)){
write(w_fd, w_buf, sizeof(w_buf));
printf("write count:%d\n", write_count++);
}
//sleep(1);
}
return 0;
}
実行コード: mkfifo 1.fifo && gcc main.c -o main && ./main 1.fifo
ベストアンサー1
if(FD_ISSET(w_fd, &w_set)){
write(w_fd, w_buf, sizeof(w_buf));
printf("write count:%d\n", write_count++);
}
select
fdが書き込み可能であると言われるならば、これは次のように書くことができるという意味です。最小1バイト。 FIFOバッファの管理方法によっては、しきい値が1より高くなる可能性がありますが、これはブロックなしで4096バイトを書き込むことができるという意味ではありません。
このコードは静的に間違っています。合理的に頑丈にするには、両方のfdを非ブロックモードに設定する必要があります(そして適切にコードを処理EAGAIN
/返すために準備する必要があります)。EWOULDBLOCK
これ理由w_fd
読み込みバッファサイズが原因で公開される問題のいくつかは、FIFOが十分に空ですが(書き込み可能に見えるように)書き込みを完了するのに十分すぎて(したがってブロック)状況に到達できるかどうかに関するものです。
ブロックされたプロセスにデバッガを接続するか、straceで実行してそれを確認または偽造することができます。これらは使い方を学ぶ必要がある完全に一般的なツールです。