0

知りたい:

close のとき、パイプのファイル記述子にはpipeどのようなステータスが設定されますか?poll

以下のコードを試してみます。子プロセスがすべてのファイル記述子を閉じた後、ポーリングはすべてのファイル記述子が読み取れると考えます! そうですか?または、このコードで間違いを犯しただけですか?

SUSE と gcc を使用しています。

#include <stdio.h>
#include <unistd.h>
#include "../../../myInclude/apue.h"// this is ok

#include <sys/poll.h>

int main(int argc, char **argv)
{
    int fd1[2]; int fd2[2]; int fd3[2];
    pid_t pid;
    if(pipe(fd1)<0 ||pipe(fd2)<0 ||pipe(fd3) <0)
        err_sys("pipe error");//this is a error deal function .it will exit the program and print error message.
    if((pid = fork()) <0)
        err_sys("fork() error");
    else if(pid == 0)
    {
        close(fd1[0]);
        close(fd2[0]);
        close(fd3[0]);

        if(write(fd1[1],"hello fd1 write!",17)!= 17)
            err_sys("write 1error ");
        sleep(2);
        if(write(fd2[1],"hello fd2 write!",17)!=17)
            err_sys("write 2error");
        sleep(2);
        if(write(fd3[1],"hello fd3 write!",17)!= 17)
            err_sys("write 3error");
        sleep(2);
        close(fd1[1]);
        close(fd2[1]);
        close(fd3[1]);
    }
    else
    {
        close(fd1[1]);
        close(fd2[1]);
        close(fd3[1]);
        struct pollfd fd[3];
        fd[0].fd = fd1[0];
        fd[1].fd = fd2[0];
        fd[2].fd = fd3[0];
        fd[0].events = POLLIN;
        fd[1].events = POLLIN;
        fd[2].events = POLLIN;
        while(poll(fd,3,3000) >0)
        {
            printf("now I come \n");
            int i = 0,n;
            char line[MAXLINE];
            for(; i< 3; i++)
            {
                if(fd[i].revents = POLLIN)
                        if ((n =read(fd[i].fd,line,MAXLINE))< 0)
                            err_sys("read error : %d",i);
                        else
                        {
                            line[n] = 0;
                            printf("read from pipe %d : %s\n",i,line);
                        }
            }
        }
        close(fd1[0]);
        close(fd2[0]);
        close(fd3[0]);
    }

    return 0;
}

子プロセスがすべての書き込みファイル記述子を閉じた後、ポーリングはrevents POLLHUPを設定すると思いますが、 POLLINを設定しただけです!

私はその本を読んでいます。私はこれが古い本であることを知っています。だから私は投票が今どのように機能するか知りたいですか?close pipe にPOLLINを設定していますか?それともLinuxだからですか?それとも私のコードが間違っていますか?

4

2 に答える 2

4

プログラムは常に-Wallオプションを付けてコンパイルする必要があります (少なくとも)。それはこの問題についてあなたに言ったでしょう:

if(fd[i].revents = POLLIN)

POLLINこれは比較ではなく割り当てであり、ゼロ以外であるため、条件は常に真になります。次の例も正しくありませんが、その方が適切です。

if(fd[i].revents == POLLIN)

POLLINで唯一のフラグが設定されている場合、それは true になりますrevents。おそらくそれがあなたがチェックしたいと思ったものですが、通常のテストは次のようになります。

if(fd[i].revents & POLLIN)

POLLINビットが設定されているかどうかをチェックし、areadがブロックしないことを示します。

エラーケースは、読み取りが失敗した後に検出できるため、たとえばPOLLHUPが設定されているかどうかを確認する必要はありません。入力ソケットでテストすることはお勧めできません。POLLHUPデータが読み取れる場合でもフラグが設定される可能性があり、通常はデータを読み取ることが望ましいからです。

于 2013-08-18T17:00:18.820 に答える
2

select()パイプの書き込み側が閉じられると、読み取り側はandに「読み取り可能」に見えますpoll()- これは aread()がブロックしないためです。

を呼び出すread()と、戻り値はゼロになり、ファイルの終わりを示します。

于 2013-08-18T14:31:41.150 に答える