【发布时间】:2021-09-02 19:15:25
【问题描述】:
我有一个 C 程序,它在循环中的某个点分叉一个子进程。子进程等待父进程完成其工作(一些数值计算)。如果出现问题,父进程中止,子进程应该从分叉时的状态继续,并通过一些修改重试计算。否则,父进程继续运行,子进程应该被杀死。
父子进程之间的通信是通过一个内存映射文件进行的,该文件只有1个字节作为一个字符,表示父进程的状态。
内存映射是这样完成的
char child_flag[]="W";
fp1 = fopen( "child_interface.dat","wb");
// the interface file has two bytes, but only one is meaningful to the program
fwrite(child_flag, 1, sizeof(child_flag), fp1);
fclose(fp1);
printf("child_interface.dat created\n");
if(mmap_child_flag() ==0) {
printf("memory map of parent-child interface successful.\n");
fflush(stdout);
}
子进程中的等待循环是这样的
child_pid = fork();
if (child_pid ==0) { /* child process, wait for parent process to finish*/
mmap_child_flag();
while(child_file[0]=='W' ){ //Child waits
usleep(100000);
}
if(child_file[0]=='R'){ // run child process (as a new parent process)
child_file[0]='W';
goto label2;
}
if(child_file[0]=='K'){ //Kill child process
exit(0);
}
}
问题是子进程似乎陷入了睡眠 while 循环,即使父进程已将状态设置为“K”(检查了内存映射的文件)。这段代码已经在几台基于 linux 的超级计算机上运行过,行为似乎很不一致。在某些平台上,它可以顺利运行,但在另一些平台上,它会不断卡在 while 循环中。有时,如果我在调用 usleep 之后在 while 循环中添加一些语句,它就可以正常运行。
但是,我不确定 sleep while 循环是否是此问题的根本原因。我的猜测是,因为该进程除了检查内存中的一个字节之外几乎无事可做,因此系统让它一直处于休眠状态并以某种方式“忘记”让它检查内存。 Linux系统会不会发生这样的事情?
这是执行实际映射的函数
/* Memory map for parent-child processes interface */
int mmap_child_flag()
{
int fd_child;
struct stat st_child;
// open files
if ((fd_child = open("child_interface.dat", O_RDWR)) == -1){
perror("open child_interface.dat");
exit(1);
}
// stat
if (stat("child_interface.dat", &st_child) == -1){
perror("stat of child_interface.dat");
exit(1);
}
// map, child_file is global char array
child_file = mmap(0, st_child.st_size, PROT_WRITE, MAP_SHARED, fd_child, 0);
if (child_file == (char *)(-1)) {
perror("mmap child_interface.dat");
exit(1);
}
return 0;
}
【问题讨论】:
-
一旦子进程产生,它就会获得自己的
child_file数组副本。父母对自己的副本所做的任何事情都不会反映在孩子的副本中。您需要研究进程间通信技术来进行通信。或转到线程。 -
child_file是如何设置在main中的? -
@SGeorgiades 我已在说明中添加了此信息。我还忘了提到子进程在分叉后也会映射文件。
-
@Serge 我忘了提到子进程在分叉后也会重做接口文件的mmap。这会改变行为吗?
-
@user556071 假设您在映射中使用
MAP_SHARED标志之一,它可以工作。您可能还需要使用msync()。
标签: c linux fork sleep memory-mapped-files