我有这个应该创build三个subprocess的代码,每个将执行一个小的math运算。 然后,父母应该使用来自所有subprocess的结果“并得到最终答案,但是我无法find一种方法来实际读取父进程中的subprocess的结果。 有没有办法做到这一点?
#include <stdio.h> #include <unistd.h> #include <stdlib.h> int main(void) { int pid1, pid2, pid3, status; int a=1, b=2, c=5, d=4, e=6, f=3, g; int t1, t2, t3; printf("Hello World!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!\n"); printf("Here I am before use of forking\n"); printf("I am the PARENT process and pid is : %d\n",getpid()); pid1 = fork( ); if (pid1 == 0) { printf("\n\nHere I am just after child forking1\n"); printf("I am the Child process and pid1 is :%d\n",getpid()); printf("My parent's pid is :%d\n",getppid()); t1 = a+b; printf("The answer for t1 is: %d\n", t1); exit(0); } else { wait(&status); printf("\nHere I am just after parent forking1\n"); printf("I am the Parent process and pid is: %d\n",getpid()); } pid2 = fork( ); if (pid2 == 0) { printf("\n\nHere I am just after child forking2\n"); printf("I am the Child process and pid2 is :%d\n",getpid()); printf("My parent's pid is :%d\n",getppid()); t2 = c+d; printf("The answer for t2 is: %d\n", t2); exit(0); } else { wait(&status); printf("\nHere I am just after parent forking2\n"); printf("I am the Parent process and pid is: %d\n",getpid()); } pid3 = fork( ); if (pid3 == 0) { printf("\n\nHere I am just after child forking3\n"); printf("I am the Child process and pid3 is :%d\n",getpid()); printf("My parent's pid is :%d\n",getppid()); t3 = e/f; printf("The answer for t3 is: %d\n", t3); exit(0); } else { wait(&status); printf("\nHere I am just after parent forkingALL\n"); printf("I am the Parent process and pid is: %d\n",getpid()); } printf("\n\nThe final answer for t1 is: %d\n", t1); printf("The final answer for t2 is: %d\n", t2); printf("The final answer for t3 is: %d\n", t3); g = t1*t2-t3; printf("The final answer for g is: %d\n", g); }
你可以用一个非常简单的技术来做到这一点,这就是共享内存 。 我将举一个完整的例子来说明它的工作原理。
首先,我们假设我想编写一个程序来打印斐波那契数列中的前n
项 (我知道这样做不合逻辑,但这是一个简单的例子,所以每个人都可以理解)。
n
项的整数值 #include <stdio.h> #include <stdlib.h> #include <sys/mman.h> #include <fcntl.h> #include <sys/stat.h> void printFibo(int n, int *fibo) { int i; for(i=0; i<=n; i++) printf("%d -> %d\n" ,i, fibo[i]); } void computeFibo(int n, int *fibo) { int i; fibo[0] = 0; fibo[1] = 1; for (i=2; i<=n; i++) fibo[i] = fibo[i-1] + fibo[i-2]; } int main(int argc, char *argv[]) { pid_t childPID; int status; int shm_fd; int* shared_memory; int msize; // the size (in bytes) of the shared memory segment const char *name = "FIBONACCI_SERIES"; int n; if (argc!=2) { fprintf(stderr, "usage: %s <Fibonacci number to be generated>\n", argv[0]); return -1; } n = atoi(argv[1]); if (n < 0) { fprintf(stderr, "Illegal fibonacci number: %s\n", argv[1]); return -2; } // calculating the array size based on the number of terms being passed from child to parent msize = (n+2)*sizeof(int); // open the memory shm_fd = shm_open (name, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG); if (shm_fd < 0) { fprintf(stderr,"Error in shm_open()"); return -3; } printf("Created shared memory object %s\n", name); // attach the shared memory segment ftruncate(shm_fd, msize); printf("shmat returned\n"); // allocating the shared memory shared_memory = (int *) mmap(NULL, msize, PROT_READ | PROT_WRITE, MAP_SHARED, shm_fd, 0); if (shared_memory == NULL) { fprintf(stderr,"Error in mmap()"); return -3; } printf("Shared memory segment allocated correctly (%d bytes).\n", msize); shared_memory[0] = n; childPID=fork(); if ( childPID == -1 ) { fprintf(stderr, "Cannot proceed. fork() error"); return -4; } if (childPID == 0) { // then we're the child process computeFibo(shared_memory[0],shared_memory+1); exit(0); } else { // parent will wait until the child finished wait(&status); // print the final results in the printFibo(shared_memory[0], shared_memory+1); // now detach the shared memory segment shm_unlink(name); } return 0; }
fork
创建一个进程的副本,所以一旦你调用fork
子进程,你有望从父进程读取变量t1,t2和t3的变量。
所以一旦你exit
孩子,孩子们就会随着他们所在的计算值而死亡。
如果你想读取儿童的值,你必须使用pipes
或共享内存。
如果你不想使用任何沟通方式,如管道,共享内存,那么你将不得不使用exit()
系统调用。 exit
系统调用返回一个信号,然后在父进程中通过wait()
系统调用捕获该信号。 在这里,我给你一个代码,我发送一个值从孩子到父母。 最后一件事,你必须等待255等待的信号,以得到确切的价值。 `
#include<unistd.h> #include<stdio.h> #include<stdlib.h> #include<sys/types.h> #include<sys/wait.h> int main(int argc,char *argv[]) { pid_t pid=fork(); if(pid==0) {//child int sum=5+7; exit(sum);//sending exiting status or any value to parent } else {//parent int childval=-1; wait(&childval);//catching signal sent by exit of(child) printf("%d",childval/255);//changing signal to exact value } return 0; }
`
您必须在父进程中创建管道,而不是在fork之后,必须关闭子进程中的输入文件描述符并关闭父进程中的输出文件描述符。
从管道(2)手册页有例子。
#include <sys/wait.h> #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <string.h> int main(int argc, char *argv[]) { int pipefd[2]; pid_t cpid; char buf; if (argc != 2) { fprintf(stderr, "Usage: %s <string>\n", argv[0]); exit(EXIT_FAILURE); } if (pipe(pipefd) == -1) { perror("pipe"); exit(EXIT_FAILURE); } cpid = fork(); if (cpid == -1) { perror("fork"); exit(EXIT_FAILURE); } if (cpid == 0) { /* Child reads from pipe */ close(pipefd[1]); /* Close unused write end */ while (read(pipefd[0], &buf, 1) > 0) write(STDOUT_FILENO, &buf, 1); write(STDOUT_FILENO, "\n", 1); close(pipefd[0]); _exit(EXIT_SUCCESS); } else { /* Parent writes argv[1] to pipe */ close(pipefd[0]); /* Close unused read end */ write(pipefd[1], argv[1], strlen(argv[1])); close(pipefd[1]); /* Reader will see EOF */ wait(NULL); /* Wait for child */ exit(EXIT_SUCCESS); } }