【问题标题】:named Piped C issue命名管道 C 问题
【发布时间】:2016-03-30 22:04:33
【问题描述】:

我有这个 C 代码:

   #define BUFSIZE 256
    int main ( int argc, char *argv[])
    {
        int fdIn;
        int fdOut;


        if( argc != 3)
        {
            perror("Error argument");
            exit(1);
        }
        printf("Input Pipe\n");
        if( (fdIn = open(argv[1], O_RDONLY ) )<0)
        {
            perror("Error opening input pipe");
            exit(1);
        }
        printf("Output Pipe\n");
        if( (fdOut = open(argv[2], O_WRONLY ) )<0)
        {
            perror("Error opening output pipe");
            exit(1);
        }

        int c = 2;
        printf("Start cicle\n");
        while(c--)
        {
            char var1[BUFSIZE];
            char var2[BUFSIZE];
            char string[100];

            memset(var1, 0, sizeof(var1));
            memset(var2, 0, sizeof(var2));
            memset(string, 0, sizeof(string));


            if( readLine(fdIn, var1, sizeof(var1)) == 0)
            {
                printf("exit \n");
                exit(0);
            }

            if( readLine(fdIn, var2, sizeof(var2)) == 0)
            {
                printf("exit \n");
                exit(0);
            }



            if( atoi(var2) != 0){
                if( atoi(var1) == 0  || (atoi(var1) % atoi(var2)) == 0 )
                    sprintf(string,"ok\n");
                else
                    sprintf(string,"no\n");

            }

            printf("%s", string);
            writeLine(fdOut, string, strlen(string));
        }
        close(fdOut);
        close(fdIn);
        exit(0);
    }

代码中的函数:

int readLine( int fd, char* str, int bufferSize)
{
    return readToDel(fd, '\n', str, bufferSize);
}

int readToDel( int fd, char delimiter, char* str, int bufferSize)
{
    int n;
    int byteLetti =0;
    int index=0;


    do /* Read characters until NULL or end-of-input */
    {

        if( (n = read (fd, str+index, 1)) < 0)
        {
            perror("Error descriptor\n");
            exit(1);
        }
        byteLetti+=n;


    }
    while (n > 0 && *(str+index++) != delimiter && index < bufferSize);


    return byteLetti; /* Return false if end-of-input */
}
int writeLine(int fd, char* buffer, int bufferSize)
{
    if( write (fd, buffer, bufferSize) < 0)
    {
        perror("Error");
        exit(1);
    }
}

我的问题是如何使用这些管道,我会解释:

我有 2 个输入管道(输入的程序是 2 个绝对管道的路径),其中一个管道是输入,另一个是输出。 在输入管道中有一些数据(特别是两个数字),经过详细说明,我必须在输出管道中写“ok”或“no”。 出于这个原因,通过终端,我做了echo "4\n2\n" &gt; input,所以我在输入的管道中写入了两个数字。 然后我这样执行程序:

./program inputPipeAbsolutePath outputPipeAbsolutePath

但程序在第三个 if 语句从 start 之前阻塞在行 printf("Output Pipe\n"); 上,我不知道为什么。 怎么了?

我在 Mac 上测试过

更新 没有人可以帮助我吗?

【问题讨论】:

  • 我认为你混淆了管道和流......
  • 你能解释一下我做错了什么吗?我是管道新手
  • 对参数使用 perror 可能会导致错误消息,例如:“错误参数:成功”或“错误参数:不是打字机”。当您不关心 errno 的值时,只需使用 fprintf(或 fputs)即可。
  • 您是从管道读取数据吗?我怀疑它不是在 printf 上阻塞,而是在 open 上。您是否在 gdb 中运行它并看到它通过了打开,或者您是否假设它在 printf 上阻塞,因为您没有看到输出?在有读者之前,打开不会完成。
  • 我同意@WilliamPursell。除非您正在写入管道并且没有读者,否则您不会阻塞 printf - 但我不能确定。您粘贴的代码无法为我编译。你是如何建造这个的?如果我要尝试帮助您进行故障排除,我真的需要一个工作示例。能否请您显示文件的所有内容以及您用于构建和执行的命令?

标签: c linux pipe


【解决方案1】:

输出管道打开时程序阻塞,我不知道 如何表现。

程序的行为与文档一致;见man fifo:

通常,打开 FIFO 会阻塞,直到另一端也打开。

因此,您的一个选择是启动一个从您的输出管道读取的程序(例如cat);然后您的程序将继续。
另一种选择是使用 O_RDWR 而不是 O_WRONLY:

在 Linux 下,打开一个 FIFO 进行读写都会成功 阻塞和非阻塞模式。 POSIX 未定义此行为。 这可用于打开 FIFO 进行写入,而没有 可用的读者。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2010-12-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-03-31
    • 1970-01-01
    相关资源
    最近更新 更多