Linux 将值从子进程传递给父进程
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/12499745/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Pass the value from child to parent process
提问by KobeBryant
I have this code that is supposed to create three child process' and each will perform a small mathematical operation. Then, the parent is supposed to use the results from all the child process' and get a final answer but I can't find a way to actually read the result from the child in the parent. Is there a way to do this?
我有这段代码应该创建三个子进程,每个子进程都将执行一个小的数学运算。然后,父进程应该使用来自所有子进程的结果并得到最终答案,但我找不到一种方法来实际读取父进程中子进程的结果。有没有办法做到这一点?
#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);
}
回答by P.P
fork
makes a copy of the process, so once you call fork
child processes have their own copy of the variables t1, t2 and t3 which you expect to read from the parent.
fork
制作进程的副本,因此一旦您调用fork
子进程,就会拥有自己希望从父进程读取的变量 t1、t2 和 t3 的副本。
So once you exit
children, the children die along with the calculated values which are local to them.
因此,一旦您成为exit
孩子,孩子们就会随着他们本地的计算值而死亡。
If you want to read values from children, you have to use pipes
or shared memory.
如果你想从孩子那里读取值,你必须使用pipes
或共享内存。
回答by alex_ac
You have to create pipe in the parent process, than after fork you must to close input file descriptor in the child process and close output file descriptor in the parent process.
您必须在父进程中创建管道,而不是在 fork 之后您必须关闭子进程中的输入文件描述符并关闭父进程中的输出文件描述符。
There is example from the pipe(2) man page.
pipe(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);
}
}
回答by Ahmed Hamdy
You can do this with a very easy technique, which is shared memory. I will give a complete example of how it works.
您可以使用一种非常简单的技术来做到这一点,即共享内存。我将给出一个完整的例子来说明它是如何工作的。
First, let's assume I want to write a program to print the first n
terms in Fibonacci series(and I know it is not that logical to do so, but it is an easy example so everyone can understand it).
首先,让我们假设我想编写一个程序来打印n
斐波那契数列中的第一项(我知道这样做不合逻辑,但这是一个简单的示例,因此每个人都可以理解)。
- I have a parent which reads an integer value representing the first
n
terms - Then the parent process will create a child and pass
n
to it - Then the child should calculate the first n terms and return them back to the parent.
- 我有一个父级,它读取一个表示第一
n
项的整数值 - 然后父进程会创建一个子进程并传递
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;
}
回答by Muhammad Raghib
If you want to do it without using any way of communication i.e pipes, shared memory then you will have to use exit()
system call. The exit
system call return a signal that is then caught by wait()
system call in parent process. Here I am giving you a code in which I am sending a value from child to parent. One last thing you have to divide the signal caught by wait by 255 to get the exact value.
`
如果您想在不使用任何通信方式(即管道、共享内存)的情况下执行此操作,则必须使用exit()
系统调用。该exit
系统调用返回,然后由捕获的信号wait()
在父进程的系统调用。在这里,我给你一个代码,我在其中将值从孩子发送到父母。最后一件事,您必须将 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;
}
`
`