藍森林首頁 | 返回主頁 | 本站地圖 | 站內搜索 | 聯繫信箱 |
 您目前的位置:首頁 > 自由軟件 > 技術交流 > 應用編程


    

藍森林 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判斷某個描述符就緒後為何一直認為他是就緒的?

問題已解決,多謝各位的幫助!



Copyright © 1999-2000 LSLNET.COM. All rights reserved. 藍森林網站 版權所有。 E-mail : webmaster@lslnet.com