簡體   English   中英

如何在Unix中將參數從父進程傳遞給子進程?

[英]How to pass arguments from parent process to child process in Unix?

在我的代碼中,我想...

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

這是使用 fork() 創建子進程的代碼

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

int main() {
    pid t pid;
    /* fork a child process */
    pid = fork();
    if (pid < 0) { /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) { /* child process */
        execlp("/bin/ls","ls",NULL);

    }
    else { /* parent process */
        /* parent will wait for the child to complete */
        wait(NULL);
        printf("Child Complete");
    }
    return 0;
} // end of main

我的問題是...

  • 我將如何使用代碼邏輯並將其與使用 fork() 的子進程創建結合起來? 如果pid == 0,那么子進程的創建成功,所以我認為這是我們插入步驟2的代碼...... 2)子進程將計算數組中所有具有奇數索引的元素的產生.

  • 父進程如何將數組發送到子進程,以便子進程可以對具有奇數索引的元素求和?

更新代碼:我將上面的兩個代碼合二為一

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

/*
calculate the production of all elements with odd index inside the array
*/
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() {
    pid t pid;
    /* fork a child process */
    pid = fork();
    if (pid < 0) { /* error occurred */
        fprintf(stderr, "Fork Failed");
        return 1;
    }
    else if (pid == 0) { /* child process */
        print("I am the child process");
        // the child process will calculate the production 
        // of all elements with odd index inside the array
        calc();
        // the child process will provide the result to the parent process 
        // when it finish calculation and then the child process will terminate
        exit(0);

    }
    else { /* parent process */
        /* parent will wait for the child to complete */
        printf("I am the parent, waiting for the child to end");
        // the parent process will create an array with at least 10 element
        int arr[] = { 1, 2, 5, 5, 6, 4, 8, 9, 23, 45 };
        int sum = calc(arr);
        wait(NULL);
        printf("Child completed calculating the production of all elements with odd index inside the array");
        // the parent will calculate the production after it get the result from the child process
        // the parent process will finally output the results.
        printf("Sum of all odd indexs element is : %d", sum);
    }
    return 0;
} // end of main

進程間通信(IPC) 機制允許您在進程之間傳遞信息。

通常, fork是在類 Unix 系統中創建新進程的唯一方法。 此時,子進程繼承父進程的代碼和地址空間。 這意味着此時 child 是 parent 的副本(在某種程度上,請參見上面的鏈接)。

在現代 Unix 變體和 Linux 中, fork是使用寫時復制頁面實現的。 這只是意味着當父進程或子進程試圖修改共享內存頁面時,操作系統會創建該頁面的副本。 現在父母和孩子都有自己的記憶頁面。

系統調用exec用新的進程映像替換當前進程映像。 這意味着父進程和子進程現在不會共享任何內存頁面或代碼。

在您的程序中,您不應調用execlp() 利用寫時復制機制的優點。 因此,在定義arr之后,在代碼邏輯程序的main()函數中執行fork() 然后從子進程訪問arr 使用wait()系統調用使父進程被阻塞,直到子進程沒有完成。

您應該使用 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;
}

這里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;
}

ps- 這里的數組是在 fork() 之后聲明的,因此它對父進程和子進程都是通用的。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM