在main()
中,我调用一个函数create_child()
,它会生成一个子进程,然后执行一个在后台运行的命令。我使用getpid()
来获取全局变量中子项的pid,该变量由主循环中的父项访问。但是,我没有在主循环中看到子pid值。
以下是伪代码 -
pid_t pids[2];
create_child(cmd,counter) {
i=fork();
if(i<0) exit(1);
if(i==0) {
pids[counter]=getpid();
ret=system(cmd);
//when system returns exit 0;
}
}
main() {
counter=0;
create_child(cmd,counter);
if (pids[counter]==xxx) {
-----
}
}
答案 0 :(得分:1)
我使用
getpid()
来获取全局变量中子项的pid,该变量在主循环中由访问。
当您执行fork
时,会为该孩子制作父母地址空间的副本。因此,子项将拥有父项变量的副本,但是修改父项或子项中的任何变量都不会看到对另一项变量的更改。
来自fork
的联机帮助页:
成功时,父进程返回子进程的PID,并在子进程中返回0。
如果要在父项中记录子项的PID,请让父项存储fork
的返回值。如果fork
的返回值不为0,那么您就在父级中。从这里,让父存储PID。即:
pid_t ret = fork();
if (ret < 0) { /* failed */ }
else if (ret == 0) { /* child, do exec */ }
else { /* parent, store PID */ }
答案 1 :(得分:0)
你需要一根管子来取回pid。当你分叉时,孩子会继承进程当前变量的副本。如果要存储子进程所做的任何更改,则必须将它们传递给父进程: 伪代码:
int fd[2];
int id;
pipe(fd);
id = fork();
if (id == 0)
{
close (fd[0]);
pid = getpid();
write (fd[1], pid, nbytes)
exit(0);
}
else
{
close(fd[1]);
read(fd[0], buffer, nbytes);
}
然后您可以自由使用缓冲区来修改全局变量。
答案 2 :(得分:0)
1)一旦父进程分叉了一个新进程,新进程就有了生命,并且它有自己的数据。新进程从父进程继承数据,并在子进程尝试修改数据时创建Child自己的副本。这种集中称为CopyOnRight。这就是为什么父母不会看到孩子做出的改变。即使您创建堆数据元素[即:动态内存分配],也适用相同的概念。我们来看下面的例子。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main (int arg, char ** argv )
{
pid_t pid;
int *p = malloc (sizeof(int));
printf ("\n Globally Assigned 99 to *p\n ");
*p= 99;
pid = fork ();
if (pid > 0)
{
printf ("\n Parent Changed *p to 100 \n ");
*p=100;
wait (NULL);
printf (" Prent Exiting..\n");
} else {
sleep(10); /* I want to give preference to my parent :) */
printf ("..Child fetching the value *p is %d \n", *p);
}
}
2)。正如@Mathieu所解释的那样,管道也可以用于两个进程之间的通信。 让我们看看下面的示例代码,该代码使用父代和子代之间的共享内存。 将其与(1)中给出的程序进行比较。看到!!!我没有做任何错误检查,因为我的意图是投射概念!!!。
#include <sys/mman.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
int main ( int arg, char ** argv )
{
int sId;
int * ptr= NULL;
pid_t pid;
/* We create a shared memory object */
sId = shm_open("MySharedData", O_RDWR|O_CREAT|O_TRUNC, 0666);
/* We allocate memory to shared object */
ftruncate (sId, 512);
/* we attach the allocated object to our process */
ptr = (int *) mmap (NULL, 512, PROT_READ|PROT_WRITE, MAP_SHARED, sId, 0);
printf ("\n Globally Assigned 99 to *p\n ");
*ptr=99;
pid = fork ();
if (pid > 0)
{
printf ("\n Parent Changed *p to 100 \n ");
*ptr=100;
wait (NULL);
printf (" Wow Child canged to %d \n", *ptr);
printf (" Prent Exiting..\n");
} else {
sleep(10); /* I want to give preference to my parent :) */
printf ("..Child fetching the value *p is %d \n", *ptr);
*ptr=1234;
}
}
在程序(2)中,您可以看到父级已被子级修改的更改,反之亦然,因为共享内存是共享内存对于父/子都是通用的,而不是同时具有单独的内存位置。
希望这有助于!!!。