如何使用execve和pipe从读取程序到主程序获取数据?

时间:2013-06-21 17:50:32

标签: c linux unix pipe execve

我正在做一个项目,因为我必须使用fork创建子进程,然后父进程告诉子进程执行另一个C程序“read.c”(它从.txt文件读取所有整数并计算平均)通过使用execve然后我必须通过管道将该平均值发送到父进程。我不知道如何在“process.c”程序的子进程中获得“read.c”程序的“平均值”。有些朋友说我必须将文件描述符传递给管道(pfd [2])用于execve和其他程序(read.c)我必须使用管道将数据写入process.c程序。但我不知道该怎么做,所以它不能正常工作。我发布了process.c和read.c的代码,请告诉我应该做些哪些更改才能使其表现良好。

process.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

main()
{

    int pid;
    int pfd[2];
    int i;
    char string1[12];
    snprintf(string1,12,"%i",pfd[1]);

    char *args[] = {"read",&string1[0],NULL};

    pipe(pfd);
    pid = fork();

    if(pid == 0)
    {

        execve("read",args,NULL);

        int size = 100;
        char buf[size]; 

        close(pfd[1]);
        read(pfd[0],buf,size);
        printf("%s\n",buf);

    }

}

read.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>


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

    int pfd[2];
    pfd[1]= atoi(argv[1]); 
    close(pfd[0]);

    FILE *ptr_file;
    char buf[1000];
    int sum = 0;
    int avg =0;
    int no = 0;
    int count = 0;

    ptr_file =fopen("data.txt","r");
    if (!ptr_file)
        return 1;

    while (fgets(buf,1000, ptr_file)!=NULL)
    {
        printf(" %s \n",buf);
        no = atoi(buf);
        sum = sum + no;
        printf("Sum = %d \n", sum);
        count++;
    }

    fclose(ptr_file);
    avg = sum/count;
    printf("Average : %d \n",avg);
    write(pfd[1],"hello",6);/*i just write here hello to see that it is working or not*/
    return 0;
} 

如果你有任何解决方案从read.c文件输出到process.c的子进程,那么请告诉我。

1 个答案:

答案 0 :(得分:0)

您的“read.c”应将结果打印到标准输出。因此,打开文件并按原样计算结果。然后使用printf()打印结果。这可以从命令行运行,输出应该到终端。

printf("%f\n", result);
close (1); // Just in case, Making sure to flush for pipe

以下是在父级和子级之间建立管道的代码。我认为这应该有助于解决您的项目。

发布process.c

#include<stdio.h>
#include<unistd.h>
#include<stdlib.h>

int main (int argc, char *argv[], char *envp[])
{
    int fd[2], pid;

    pipe (fd);
    pid = fork()

    if (pid == 0)
    {
        /* Child process */
        close (1);       // Close STDOUT.
        dup(fd[1]);      // STDOUT will be fd[1]
        close (0);       // Close STDIN, Don't need this.
        close (2);       // Close STDERR, Don't need this.
        close (fd[0]);   // Don't need this.
        close (fd[1]);   // Don't need this.

        execvpe ("./read", argv, envp); // Choose your exec() version

        /* exec() family of calls never returns. Process reed executes here. */
    }
    else
    {
        /* Parent process executes here */

        char chr[256];
        float average = 0;
        int ret = 0;

        /* Parent process. Making it very simple without any dups etc. */
        /* No error checks are performed... */
        /* You may experiment with enhancements here!!! */

        ret = read (fd[0], chr, 255); // Blocking Read syscall
        if (ret <= 0) 
        {
            printf ("Error or Nothing is read. Debug the problem!!!\n");
            exit (1);
        }

        chr[ret] = '\0';
        printf ("Average from read Child process[PID is %d] = %s\n", pid, chr);
    }
}