如何解决使用fork调用后如何在进程之间传递值?
我需要创建一个程序,该程序将开始4个进程之间的竞赛,以从用户输入中获取数字。用户将输入4个数字(1到4),接收第一个数字(1)的过程将是赢家,而在第一位,其后的过程将获得第二,第三和第四位,具体取决于他们从用户。
该程序将通过使用fork()系统调用来创建4个进程,每个创建的进程由1到4的数字标识,该数字指示其创建顺序。例如,创建的第一个子进程的get 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",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",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",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",procNUM,runNum);
//fflush(stdout);
runNum++;
}
else if (p1 == 0 && p2 > 0)
{
//child 1
scanf("%d",runNum);
//fflush(stdout);
runNum++;
}
else if (p1 > 0 && p2 == 0)
{
//child 2
scanf("%d",runNum);
// fflush(stdout);
runNum++;
}
else {
//child 3
scanf("%d",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],&ret_code[i]);
}
for (i = 0 ; i < N ; i++)
pthread_join(&thread[i],NULL);
// C11: thrd_join(thread[i],NULL);
return 0;
}
由于您的子进程为标准输入处理“竞争”,所以我建议启动像“ xterm”或其他终端仿真程序之类的子进程-这样,输入可以真正“竞争”。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。