|
藍森林 http://www.lslnet.com 2006年6月6日 10:18
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
[code]
#include <stdio.h>;
#include <stdlib.h>;
#include <string.h>;
#include <sys/ipc.h>;
#include <sys/stat.h>;
#include <fcntl.h>;
#include <sys/types.h>;
#include <unistd.h>;
#include <sys/time.h>;
#include <errno.h>;
#define MAXLINE 1024
#define FILE_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IXOTH)
int main()
{
int readfd[3];
int writefd[3];
pid_t pid[3];
char fifo_name1[MAXLINE];
char fifo_name2[MAXLINE];
char buff[MAXLINE];
char chin[MAXLINE];
fd_set rdfd;
FD_ZERO(&rdfd);
int m,n;
m=0;
int i;
for(i=0;i<3;i++)
{
printf("number %d\n",i);
if((pid[i]=fork())==0)
{
pid_t childpid;
childpid=getpid();
printf("this child %d\n",i);
//sleep(1);
snprintf(fifo_name1,sizeof(fifo_name1),"/tmp/fifo.%ld",(long)childpid);
snprintf(fifo_name2,sizeof(fifo_name2),"/tmp/fifoserv.%ld",(long)childpid);
printf("in child,fifo_name1:%s\n",fifo_name1);
printf("in clild,fifo_name2:%s\n",fifo_name2);
readfd[i]=open(fifo_name1,O_RDONLY,0);
//printf("in child,fifo_name1:%s\n",fifo_name1);
writefd[i]=open(fifo_name2,O_WRONLY,0);
snprintf(buff,sizeof(buff),"this is child %d",i);
printf("in child %d,send to father: %s\n",i,buff);
write(writefd[i],buff,sizeof(buff));
int j;
for(j=0;j<5;j++)
{
memset(buff,0,sizeof(buff));
read(readfd[i],buff,sizeof(buff));
printf("get from server:%s(%d times)\n",buff,j);
}
close(readfd[i]);
close(writefd[i]);
}
printf("in father!\n");
snprintf(fifo_name1,sizeof(fifo_name1),"/tmp/fifo.%ld",(long)pid[i]);
printf("in father fifo1 is %s\n",fifo_name1);
snprintf(fifo_name2,sizeof(fifo_name2),"/tmp/fifoserv.%ld",(long)pid[i]);
printf("in father fifo2 is %s\n",fifo_name2);
if((mkfifo(fifo_name1,FILE_MODE)<0)&&(errno!=EEXIST))
{
printf("can't create %s\n",fifo_name1);
exit(1);
}
if((mkfifo(fifo_name2,FILE_MODE)<0)&&(errno!=EEXIST))
{
unlink(fifo_name1);
printf("can't create %s\n",fifo_name2);
exit(1);
}
writefd[i]=open(fifo_name1,O_WRONLY,0);
readfd[i]=open(fifo_name2,O_RDONLY,0);
FD_SET(readfd[i],&rdfd);
printf("m=%d\n",m);
printf("readfd[%d]=%d\n",i,readfd[i]);
m=readfd[i]>;m?readfd[i]:m;
n=m+1;
printf("n=%d\n",n);
select(n,&rdfd,NULL,NULL,NULL);
//問題????????????????
//在這裡,應該只向writefd[0]發送一次chin,但是,他居然一直向子進程發送
if(FD_ISSET(readfd[0],&rdfd))
{
read(readfd[0],chin,sizeof(chin));
printf("server get from client 0:%s\n",chin);
int j;
for(j=0;j<3;j++)
if(writefd[j]>;0) write(writefd[j],chin,sizeof(chin));
memset(chin,0,sizeof(chin));
}
if(FD_ISSET(readfd[1],&rdfd))
{
read(readfd[1],chin,sizeof(chin));
printf("server get from client 1:%s\n",chin);
int j;
for(j=0;j<3;j++)
if(writefd[j]>;0) write(writefd[j],chin,sizeof(chin));
memset(chin,0,sizeof(chin));
}
if(FD_ISSET(readfd[2],&rdfd))
{
read(readfd[2],chin,sizeof(chin));
printf("server get from client:%s\n",chin);
int j;
for(j=0;j<3;j++)
if(writefd[j]>;0) write(writefd[j],chin,sizeof(chin));
memset(chin,0,sizeof(chin));
}
}
}
[/code]
[b]
在FD_ISSET認為某個描述符就緒後,如何才能在執行完一系列操作之後重新變為非就緒態?
[/b] |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
FD_SET(readfd[i],&rdfd);
select(n,&rdfd,NULL,NULL,NULL);
if(FD_ISSET(readfd[0],&rdfd))
if(FD_ISSET(readfd[1],&rdfd))
if(FD_ISSET(readfd[2],&rdfd))
當readfd[0]返回後,你本身發送的可能不只一次。
for(j=0;j<3;j++)
if(writefd[j]>;0) write(writefd[j],chin,sizeof(chin));
在FD_ISSET認為某個描述符就緒後,如何才能在執行完一系列操作之後重新變為非就緒態?
select一旦認為某個描述符就緒後,會在此返回的,如果進程阻塞在一個FD_ISSET內部,就看不到這種情況了! |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
這個例子只是一次性的過程吧,如果是像有些SOCKET程序一直在循環的話,每次循環進來select之前rset,wset,expectionset都要重新初始化一次,等select 返回之後,才改變這些set,可以用FD_ISSET來判斷 |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
我是在接收到一個管道(子進程)傳來的信息後將這條信息發給所有的子進程,但對於某個特定的子進程只可能接收到一條信息.
但是運行出來,第一個子進程卻一直收到.只是第一條是想要的,而其他的都是空.(這時因為我在發送一條後就把chin置空了)
所以可以確定父進程在得知readfd[0]可讀後就一直在執行發送語句,即一直認為它是就緒的 |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
:oops: 好像是select後rdfd狀態發生變化,我覺得應該 FD_SET(readfd[i],&allfd);
rdfd=allfd
select(...); |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
是的,需要重新set。 |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
我現在已經將rdfd的定義以及置空都放到了循環內部,就是每次在使用select之前都會重新FD_SET,但是FD_ISSET仍然認為描述符就緒(事實上,只有第一次有信息發過來). |
在FD_ISSET判斷某個描述符就緒後為何一直認為他是就緒的?
問題已解決,多謝各位的幫助! |
| |