簡體   English   中英

使用 fork() 調用后如何在進程之間傳遞值?

[英]How to pass values between processes after using the fork() call?

我需要創建一個程序,該程序將在 4 個進程之間開始競爭以從用戶輸入中獲取一個數字。 用戶將輸入 4 個數字(1 到 4),收到第一個數字 (1) 的進程將獲勝,在第一名之后的進程將根據他們從數字中獲得的數字獲得第二、第三和第四名。用戶。

程序開始時會使用fork()系統調用創建4個進程,創建的每個進程都用一個1到4的數字來標識,這個數字表示它的創建順序。 例如,創建的第一個子進程獲取 ID = 1。

畢竟,創建了進程,進程將開始向用戶請求一個號碼。 每個進程都會打印它從用戶那里得到的號碼,並打印它的 ID 號。 父進程不參與競爭,並在退出之前等待所有子進程完成。

我想我已經完成了基本結構,但我不確定如何在進程之間傳遞值,或者是否正在完成合法的競爭條件。 我也無法運行最后 3 個進程。

這是我的輸出:

我的輸出

這是預期的輸出:

預期產出

這是我到目前為止所擁有的:


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

    int p1, p2, num; 

int procNUM = 1, runNum = 1 ;

void game(int p1,int p2);

int main() {
    
     printf("Enter numbers for processes to race for >>>\n");

    p1 = fork();

    p2 = fork();
    
if (p1 > 0 && p2 > 0) { 
       //parent 
       
      
            printf(" I am a process with pid %d and I am process number %d in the race.\n",getpid(), procNUM);
            procNUM++;
           // fflush(stdout);
           // scanf("%d", &num);
           // printf("%d", &num);
           // printf(I am a processs with);
       
    } 
    
    else if (p1 == 0 && p2 > 0) 
    { 
    //child 1 
    
     printf(" I am a process with pid %d and I am process number %d in the race.\n",getpid(), procNUM);
     procNUM++;
    // fflush(stdout);
     
    } 
    
    else if (p1 > 0 && p2 == 0) 
    { 
    //child 2 
   
    printf(" I am a process with pid %d and I am process number %d in the race.\n",getpid(), procNUM);
    procNUM++;
    //fflush(stdout);
    
    
    } 
    
    else { 
       //child 3
       
    printf(" I am a process with pid %d and I am process number %d in the race.\n",getpid(), procNUM);
    procNUM++;
   // fflush(stdout);
   
       
        
    } 


    game(p1, p2);

 return 0;   
}


void game(int p1,int p2){
    if (p1 > 0 && p2 > 0) { 
       //parent 
            scanf("%d", &num);
            printf(" I am a process with pid %d and I am process number %d in the race and I am in %d place.\n",getpid(), procNUM, runNum);
            //fflush(stdout);
            runNum++;
       
    } 
    
    else if (p1 == 0 && p2 > 0) 
    { 
    //child 1 
    
            scanf("%d", &num);
            printf(" I am a process with pid %d and I am process number %d in the race and I am in %d place.\n",getpid(), procNUM, runNum);
            //fflush(stdout);
       runNum++;
    
    
    } 
    
    else if (p1 > 0 && p2 == 0) 
    { 
    //child 2 
   
            scanf("%d", &num);
            printf(" I am a process with pid %d and I am process number %d in the race and I am in %d place.\n",getpid(), procNUM, runNum);
           // fflush(stdout);
       runNum++;
    
    } 
    
    else { 
       //child 3
       
            scanf("%d", &num);
            printf(" I am a process with pid %d and I am process number %d in the race and I am in %d place.\n",getpid(), procNUM, runNum);
            //fflush(stdout);
       runNum++;
        
    } 
    
    
    
}





fork之后,您的 procNUM 變量“分支”並且與父進程的 procNUM 沒有任何共同之處,因此增加它不會告訴父進程任何信息(寫入時復制)。

要將值傳遞給子進程,請使用 argv[] 數組 - 它是execvp函數的參數。

我建議采用標准方式:在主程序中啟動多個線程,每個線程啟動一個子進程。 子進程(game.c)代碼很簡單:

#include <stdio.h>
int main(int argc, char** argv)
{
    int num;
    scanf("%d", &num);
    return num;
}

父程序涉及更多。

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
// #include <threads.h>
// #include <stdatomic.h>
#include <pthread.h>

// Compile the program above to  'game' using "gcc -o game game.c"
#define N (4)
const char* game_file = "./game";

// Declare PID array, ret_code and threads
int pids[N];
int ret_code[N];
pthread_t thread[N];
// C11: thrd_t thread[N];

// Each thread increments this atomic int when the child process finishes
/* C11: atomic_int */ int proc_finish_count;

線程過程是

int game_proc(void *arg) {
    int i = *((int*)arg);
    pids[i] = fork();
    if (pids[i] > 0) {
        while(1) {
            int st;
            int res = waitpid(pids[i], &st, WNOHANG);
            if (res == pids[i]) {
                proc_finish_count++;
                // In C11 use atomics :
                // atomic_fetch_add_explicit(&proc_finish_count, 1, memory_order_relaxed);
                printf(" I am a process with pid %d and I am process number %d in the race and I am in %d place.\n", pids[i], i, proc_finish_count);
                break;
            } else
            if (res < -1) {
                // error while waiting
                return 1;
            }
        }
    } else { 
        // Here you can pass parameters to `game` - insert the list of strings before NULL
        execlp(game_file, game_file, NULL);
        printf("Error running process\n");
    } 

    return 0;
}

而 main 函數只是啟動並等待線程

int main(){
    int i;
    proc_finish_count = 0;
    for (i = 0 ; i < N ; i++) {
        ret_code[i] = i; // index of the process
        pthread_create(&thread[i], NULL, &game_proc, &ret_code[i]);
        // C11: thrd_create(&thread[i], &game_proc, &ret_code[i]);
    }

    for (i = 0 ; i < N ; i++)
        pthread_join(&thread[i], NULL);
        // C11: thrd_join(thread[i], NULL);

    return 0;
}

由於您的子進程“競爭”標准輸入,我建議將諸如“xterm”或其他終端模擬器之類的東西作為子進程啟動 - 這樣輸入就可以真正“競爭”。

暫無
暫無

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

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