Как получить данные из программы чтения в основную программу, используя execve и pipe?

Я делаю проект, в котором мне нужно создать дочерний процесс с помощью fork, а затем родительский процесс сообщает дочернему процессу выполнить другую программу C «read.c» (которая считывает все целые числа из файла .txt и вычисляет среднее) с помощью используя execve, я должен отправить это среднее значение родительскому процессу через канал. Я не знаю, как получить «среднее значение» результата программы «read.c» в дочернем процессе программы «process.c». Некоторые из моих друзей сказали, что мне нужно передать дескриптор файла, полезный для канала (pfd [2]), в execve, а из другой программы (read.c) я должен использовать канал для записи данных в программу process.c. но я не знаю, как это сделать, поэтому он не работает должным образом. Я публикую свои коды как для process.c, так и для read.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);

    }

}

читать.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, сообщите мне.


person TusharU    schedule 21.06.2013    source источник
comment
Что плохого в том, чтобы передать их как две строки?   -  person    schedule 21.06.2013
comment
Домашнее задание домашнее...   -  person devnull    schedule 21.06.2013
comment
@ H2CO3 H2CO3 Я не знаю, как передать целочисленный массив в виде строки.char args[] = {read,(char)pfd,NULL}; Я пробовал это, поэтому он не дает мне никаких предупреждений, но в read.c я не получаю то, что мне нужно.   -  person TusharU    schedule 21.06.2013
comment
Возможно, этот вопрос вам немного поможет. вопросы/7383142/   -  person Marco    schedule 21.06.2013
comment
@Marco Я пробовал, чтобы это устраняло проблему приведения, но не собирало данные на другой стороне (в процессе.c)   -  person TusharU    schedule 21.06.2013
comment
Вы закрываете канал на read.c?   -  person Marco    schedule 21.06.2013
comment
Кроме того, в вашем коде у вас есть возврат перед записью. WTF.. почему вы не обновляете исходный код последними изменениями?   -  person Marco    schedule 21.06.2013
comment
@Марко, минутку.   -  person TusharU    schedule 21.06.2013
comment
@Tushar Преобразуйте его в строку. snprintf(buf, sizeof(buf), "%d", someInteger);   -  person    schedule 21.06.2013
comment
@Marco Марко, я обновил исходный код, как видите, он все еще не работает.   -  person TusharU    schedule 21.06.2013
comment
@ H2CO3 Я использовал его, вы можете видеть в обновленном исходном коде выше, но он все еще не работает.   -  person TusharU    schedule 21.06.2013
comment
@Tushar Если у вас два разных процесса, то, конечно, нет. Как насчет создания трубы вместо этого?   -  person    schedule 21.06.2013
comment
@ H2CO3 Я просто хочу получить значение int avg для read.c в дочернем процессе process.c после выполнения только что. я не знаю, как это сделать. пожалуйста, помогите мне.   -  person TusharU    schedule 22.06.2013
comment
@Tushar Кажется, вам скорее нужна общая память.   -  person    schedule 22.06.2013
comment
@H2CO3 как это сделать?   -  person TusharU    schedule 22.06.2013


Ответы (1)


Ваш "read.c" должен вывести результат на стандартный вывод. Итак, откройте файл и посчитайте результат, как вы это делаете. Затем используйте printf(), чтобы распечатать результат следующим образом. Это можно запустить из командной строки, и вывод должен перейти на терминал.

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

Вот код, который устанавливает канал между родителем и дочерним элементом. Я думаю, что это должно помочь решить ваш проект.

Фрагмент процесса.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);
    }
}
person sukumarst    schedule 22.06.2013