父进程和子进程

3
我正在尝试编写一个程序。父进程将获取main()函数的参数,并通过管道向子进程逐个发送其中的字符(每个字符调用一次write)。子进程将计算由父进程发送到它的字符数量,并打印出其接收自父进程的字符数。子进程不应以任何方式使用main()函数的参数。子进程应平稳返回而不是由父进程杀死。
我是否正确计算了参数?我是否逐个发送参数,我是否回收了子进程?
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define size = 100;

int main(int argc, char *argv[])
{

    int i, count =0;
    int c;

    int     fdest[2];          // for pipe
    pid_t   pid;              //process IDs
    char    buffer[BUFSIZ];



    if (pipe(fdest) < 0)          /* attempt to create pipe */
        perror( "pipe" );

    if ((pid = fork()) < 0)  /* attempt to create child / parent process */

    {
        perror( "fork" );
    } 


    /* parent process */
    else if (pid > 0) { 

        close(fdest[0]);
        for (i=1; i < argc; ++i) 
        {
            for (c=0; c < strlen(argv[i]); ++c) {
                write(fdest[1], &argv[i][c], 1);
            }
        }

        close(fdest[1]);         
        wait(NULL);             
        exit(0);

    } else {   

        /* child Process */
        close(fdest[1]);

        while (read(fdest[0], &buffer, 1) > 0)
        {
            count++;
        }


        printf("\nchild: counted %d characters\n", count);

    }
    wait(NULL);
    exit(0);

}

5
看起来您之前已经发布了这个问题。也许您可以解释一下这个问题与您以前的这个问题有何不同:https://dev59.com/uEzSa4cB1Zd3GeqPmGTU - Greg Hewgill
主要的区别在于写入管道时每次只能写一个字符,读取管道时也只能读取一个字符。 - Jonathan Leffler
1个回答

2
第二个`wait()`是多余的,子进程没有自己等待的孩子。第二个`exit(0);`可以替换为`return(0);`。你也可以省略之前的`exit(0);`。
`#define size = 100;`没有使用,这很好,因为'='使它对大多数目的不可用(分号也不是一个好主意 - 很少有宏以分号结尾)。应该是`#define size 100`或`enum { size = 100 };`。通常人们用大写字母表示“明示常量”,因此是 `enum { SIZE = 100 };`。
如果你每次只读取一个字符,那么你实际上不需要大小为BUFSIZ(通常为512或更大)的缓冲区。
另外,使用`for (c = 0; c < strlen(argv[c]); c++)`是一个坏习惯,因为它在每次迭代时都计算字符串的长度。请将其替换为以下两种之一:
for (const char *str = argv[i]; *str != '\0'; str++)
    write(fdest, str, 1);

for (c = 0, len = strlen(argv[i]); c < len; c++)
      write(fdest[1], &argv[i][c], 1);

你需要关闭未使用的管道端口 - 这是使事情正常工作的关键步骤。
代码似乎在正确计数。当我测试它时,它可以直接使用。你为什么怀疑它不起作用呢?

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接