2017-10-04 49 views
2

裏面我的代碼我想...如何將參數從父進程傳遞給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 

這裏是代碼使用叉創建一個子進程()

#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)子進程會計算所有元素的生產 奇數索引內陣列。

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

更新的代碼:我結合兩個以上驗證碼成一個

#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 
+0

所以,現在你只能通過'ls'傳遞'argv [0]'。如果您想傳遞更多參數,請將它們放在命令行中。這就是:'execlp(「/ path/to/your/executable」,「argument-that-become- $ 0」,「argument-that-become- $ 1」,「argument-that-become- $ 2」,「etc」 ,NULL)'。 –

+0

要在2進程之間進行通信,可以使用信號('kill()'和'signal()'或'sigaction()') – YaatSuka

+0

@YaatSuka,呃? OP不僅僅希望發送(非信息攜帶)信號,他們希望傳遞明確的值。信號沒有關於傳送順序的保證,其中有幾個含義不能被覆蓋(你不能通過'SIGKILL'傳遞'9',並且程序不以任何方式解釋爲退出,所以它沒有用作發送未知值的整數的方法)。 –

回答

1

有讓您進程之間傳遞信息inter-process communication(IPC)機制。

通常,fork是在類Unix系統中創建新進程的唯一方法。在那兒,子進程繼承父代碼和地址空間。這意味着孩子在這個時間點是父母的重複(在某種程度上,請參見上面的鏈接)。

在現代Unix變種和Linux中,fork是使用寫時複製頁面實現的。這僅表示當父進程或子進程嘗試修改共享內存頁面時,操作系統會創建此頁面的副本。現在父母和孩子有自己的內存頁面。

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

在你的程序中,你不應該打電話execlp()。使用寫入時複製機制的優點。在定義arr之後,在您的CODE LOGIC程序中,功能中的main()功能。然後從子進程訪問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; 
} 
+2

退出狀態是一個糟糕的選擇子進程將其計算結果傳遞給其父進程,因爲只有8位可供其使用(在符合POSIX的系統上,但我們似乎假設POSIX或類似的使用fork,wait和' unistd.h')。 OP的結果很可能太大了。 –

+0

非常感謝您對我有用的評論。 – boriaz50

+1

從子進程讀取結果的通常做法是設置一個FIFO對,以便孩子可以將結果寫入FIFO並關閉它,父母可以讀取並解釋它們。例如,這就是shell中的'variable = $(somecommand)'。 –

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()的聲明後,所以它是常見的兩種父子進程。

相關問題