storage R&D guy.
全部博文(1000)
分类: 服务器与存储
2015-05-04 17:56:50
基本上,创建有名管道和平常的文件操作没有太大的差别。在用select对有名管道句柄进行操作时,有些比较奇怪的地方。
例如,我们有两个程序(进程),一个向有名管道写,另一个负责从有名管道读。逻辑很简单,因此我们很自然地在读进程程序中设置read_only,然后用select等待数据。
奇怪的事情发生了,select总是能返回成功,可是read的数据为空。这个问题让我们百思不得其解,结果google后发现,对于只读的有名管道,也需要设置为“读写”模式,否则它对select总是会立刻返回成功。
经过多次测试,对linux下的有名管道,如果采用select判断是否可读,需要设置以下参数:
(1)非阻塞
(2)可读可写
例如以下演示代码:
fd = open(COMMAND_PIPE, O_NONBLOCK | O_RDWR);
... ...
int ret = select(fd+1, &read_set, NULL, NULL, &timeVal);
/*fifo_read.c*/
#include
#include #include #include #include #include #include #include #define FIFO_FILE "/tmp/fifo.tmp" #define MAXLEN 1024
int main() { int fifo,fd; char buf[MAXLEN]; int len,i = 0; fd_set set; struct timeval tv;
unlink(FIFO_FILE); if((fifo=mkfifo(FIFO_FILE,O_RDWR))<0) { perror("mkfifo error\n"); return 0; } if((fd=open(FIFO_FILE,O_RDWR))<0) { perror("open mkfifo error\n"); return 0; } FD_ZERO(&set); //FD_SET(fd,&set); tv.tv_sec = 5; tv.tv_usec = 0; while(1) { FD_SET(fd,&set); if((i=select(fd+1,&set,NULL,NULL,&tv))>0) { printf("have data in pipe\n"); if(FD_ISSET(fd,&set)) { len = read(fd,buf,MAXLEN); //buf [len]= '/0'; printf("buf =%s\n",buf); tv.tv_sec = 5; tv.tv_usec = 0; } } else if(i == 0) { tv.tv_sec = 5; tv.tv_usec = 0; printf("time out\n"); } } unlink(FIFO_FILE); return 0; }
//#gcc fifo_read.c -o fifo_read
#include
#include #include #include #include #include #define FIFO_FILE "/tmp/fifo.tmp" #define MAXLEN 1024
int main() { int fifo,fd; char buf[MAXLEN]; int len,i = 0; memset(buf,0,sizeof(buf)); strcpy(buf,"10"); if((fifo=open(FIFO_FILE,O_RDWR))<0) { perror("open mkfifo error\n"); return 0; }
while(i<10) { sprintf(buf,"%d",i+1); len = write(fifo,buf,strlen(buf)); printf("send len =%d\n",len); sleep(1); i++; }
return 0; } //#gcc fifo_write.c -o fifo_write