C 在Unix中如何将参数从父进程传递到子进程?

C 在Unix中如何将参数从父进程传递到子进程?,c,arrays,process,parent-child,child-process,C,Arrays,Process,Parent Child,Child Process,在我的代码中,我想… 1) 父进程将创建一个至少包含10个 元素 2) 子进程将计算所有元素的产量 数组中有奇数索引 3) 子进程将提供结果 当父进程完成计算后,再返回子进程 将终止 4) 父级将在获得数据后计算产量 子进程的结果 5) 父进程将最终输出 结果 现在,代码逻辑很容易编写,如下所示 int cal(int arr[10]) { int i=0; int sum = 0; for (i=1; i<10; i=i+2) { sum = su

在我的代码中,我想…

1) 父进程将创建一个至少包含10个 元素

2) 子进程将计算所有元素的产量 数组中有奇数索引

3) 子进程将提供结果 当父进程完成计算后,再返回子进程 将终止

4) 父级将在获得数据后计算产量 子进程的结果

5) 父进程将最终输出 结果

现在,代码逻辑很容易编写,如下所示

int cal(int arr[10]) {
    int i=0;
    int sum = 0;
    for (i=1; i<10; i=i+2) {
        sum = sum + arr[i];
    }

    return sum;
} // end of calc

int main() {
    int arr[] = { 10, 20, 25, 5, 6, 45, 87, 98, 23, 45};
    int sum = cal(arr);

    printf("Sum of all odd indexs element is : %d", sum);

    return 0;
} // end of main
int-cal(int-arr[10]){
int i=0;
整数和=0;
对于(i=1;i,有(IPC)机制允许您在进程之间传递信息

通常,是在类Unix系统中创建新进程的唯一方法。此时,子进程继承父进程的代码和地址空间。这意味着此时子进程是父进程的副本(在某种程度上,请参见上面的链接)

在现代Unix变体和Linux中,使用写入页上的复制实现。这只意味着当父进程或子进程尝试修改共享内存页时,操作系统会创建此页的副本。现在父进程和子进程都有自己的内存页

系统调用将当前进程映像替换为新进程映像。这意味着父进程和子进程现在不会共享任何内存页或代码

在您的程序中,您不应该调用
execlp()
。使用写时复制机制的优点。在
main()中也应该使用
fork()
定义
arr
后,在代码逻辑程序中执行
函数。然后从子进程访问
arr
。使用系统调用使父进程被阻止,直到子进程未完成

您应该使用IPC从子进程返回结果。在您的情况下,管道是最好的选择。但很明显,您做的实验室作业是关于Unix进程的,而不是关于IPC。因此,您可以通过子进程的退出代码返回结果。将结果传递给
exit()
函数。请注意,您只能传递8位(见我回答下的评论)

这是一个工作代码:

#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int calc(int *arr, int n) {
    int sum = 0;
    for (i = 1; i < n; i += 2) {
        sum = sum + arr[i];
    }
    return sum;
}

int main(void) {
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int n = sizeof(arr) / sizeof(arr[0]);

    pid_t pid = fork();
    if (pid < 0) {
        perror("fork failed");
        return 1;
    }
    else if (pid == 0) {
        printf("I am the child process\n");

        int child_sum = calc(arr, n);
        exit(child_sum);
    }
    else {
        printf("I am the parent process\n");

        int parent_sum = calc(arr, n);

        int child_sum;
        if (wait(&child_sum) == -1) {
            perror("wait failed");
        }
        else {
            printf("Sum by child: %d\n", child_sum);
        }

        printf("Sum by parent: %d\n", parent_sum);
    }

    return 0;
}
#包括
#包括
#包括
内部计算(内部*arr,内部n){
整数和=0;
对于(i=1;i
此处
execlp
将为您的子进程提供一个新的地址空间。因此您实际上无法从父进程向子进程发送参数。但您可以执行以下操作:

#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid;
    /* fork a child process */
    pid = fork();
    int sum = 0;
    int arr[] = { 10, 20, 25, 5, 6, 45, 87, 98, 23, 45};
    if (pid < 0) { /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) { /* child process */
        int i=0;

        for (i=1; i<10; i=i+2) {
            sum = sum + arr[i];
        }

        return sum;


    }
    else { /* parent process */
        /* parent will wait for the child to complete */
        wait(NULL);

    int i=0;

        for (i=1; i<10; i=i+2) {
            sum = sum + arr[i];
        }

        printf("%d\n",sum);
    }
    return 0;
}
#包括
#包括
#包括
int main(){
pid_t pid;
/*派生子进程*/
pid=fork();
整数和=0;
int arr[]={10,20,25,5,6,45,87,98,23,45};
如果(pid<0){/*发生错误*/
fprintf(标准“Fork Failed”);
返回1;
}
如果(pid==0){/*子进程*/
int i=0;

对于(i=1;iSo,现在您只通过
ls
传递
argv[0]
。如果要传递更多参数,…请将它们放在命令行上。即:
execlp(“/path/to/your/executable”,“变为-0的参数”,“变为-1的参数”,“变为-2的参数”,“等等”,NULL)
。要在两个进程之间进行通信,您可以使用信号(
kill()
signal()
sigaction()
)@YaatSuka,嗯?OP不只是想发送一个(非信息承载)信号,它们希望传递显式的值。信号没有关于交货订单的保证,其中有几个具有无法重写的含义(您不能通过
SIGKILL
传递
9
,也不能让程序以任何方式解释,而不是作为退出命令,因此作为发送未知值的整数的方式是没有用的).@YaatSuka,全局变量绝对不是在进程之间共享的。它们是从父进程复制到子进程,而不是从子进程复制到父进程。这种说法完全不真实。也许你考虑的是线程而不是进程?@YaatSuka,请看,退出状态对于子进程来说是一个糟糕的选择,无法将其计算结果传递给its parent,因为只有8位可供使用(在符合POSIX的系统上,但我们似乎通过使用
fork
wait
unistd.h
来假设POSIX或类似的系统)。OP的结果可能太大了。非常感谢您对我的有用评论。读取子进程结果的通常做法是设置FIFO对,以便子进程可以将结果写入FIFO并关闭它,父进程可以读取和解释它们。这就是
variable=$(somecommand)
例如,在shell中是这样。你是指管道吗?是的。管道是FIFO(“先进先出”)。
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>

int calc(int *arr, int n) {
    int sum = 0;
    for (i = 1; i < n; i += 2) {
        sum = sum + arr[i];
    }
    return sum;
}

int main(void) {
    int arr[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };
    int n = sizeof(arr) / sizeof(arr[0]);

    pid_t pid = fork();
    if (pid < 0) {
        perror("fork failed");
        return 1;
    }
    else if (pid == 0) {
        printf("I am the child process\n");

        int child_sum = calc(arr, n);
        exit(child_sum);
    }
    else {
        printf("I am the parent process\n");

        int parent_sum = calc(arr, n);

        int child_sum;
        if (wait(&child_sum) == -1) {
            perror("wait failed");
        }
        else {
            printf("Sum by child: %d\n", child_sum);
        }

        printf("Sum by parent: %d\n", parent_sum);
    }

    return 0;
}
#include <sys/types.h>
#include <stdio.h>
#include <unistd.h>

int main() {
    pid_t pid;
    /* fork a child process */
    pid = fork();
    int sum = 0;
    int arr[] = { 10, 20, 25, 5, 6, 45, 87, 98, 23, 45};
    if (pid < 0) { /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) { /* child process */
        int i=0;

        for (i=1; i<10; i=i+2) {
            sum = sum + arr[i];
        }

        return sum;


    }
    else { /* parent process */
        /* parent will wait for the child to complete */
        wait(NULL);

    int i=0;

        for (i=1; i<10; i=i+2) {
            sum = sum + arr[i];
        }

        printf("%d\n",sum);
    }
    return 0;
}