[英]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.