C 与分叉过程混淆?
我正在尝试执行第一个子函数,例如,打印一个字符串:hello!,然后返回到父进程。然后,我为第二个子函数分叉了另一个n进程,它将计算共享内存数。我想最后只显示了一个“全部完成”,但它显示了两个?谢谢你的帮助C 与分叉过程混淆?,c,multiprocessing,C,Multiprocessing,我正在尝试执行第一个子函数,例如,打印一个字符串:hello!,然后返回到父进程。然后,我为第二个子函数分叉了另一个n进程,它将计算共享内存数。我想最后只显示了一个“全部完成”,但它显示了两个?谢谢你的帮助 #include <stdio.h> #include <stdlib.h> #include <unistd.h> #include <sys/shm.h> #include <string.h> #include <sys
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#define NUM_LINES 5
char * shm;
void child_func(char *shm)
{
while (atoi(shm) != NUM_LINES)
{
// P(sem);
printf("now reading word:%d\n", atoi(shm) );
*shm+=1;
// V(sem);
}
exit(0);
}
void parent_func(pid_t pid)
{
int status;
pid_t pid_wait;
do
{
pid_wait = waitpid(pid, &status, WNOHANG);
}while (pid_wait != pid);
// printf("Process %d done\n", getppid());
}
int main(int argc, char const *argv[])
{
/* declarations */
pid_t pid[8];
int ret, shmid, status,corpse, i, ave, n;
char fn[20];
key_t key = 123;
char *string_back;
/* create share memory */
if ((shmid = shmget(key, SHMSIZE, IPC_CREAT|666)) <0)
{
perror("shmget");
exit(1);
}
/* attach shm */
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror("shmat");
exit(1);
}
/* init shm value */
*shm = '0';
/* input */
printf("please enter n:\n");
scanf("%d", &n);
/* section 1 */
pid[0] = fork();
if (pid[0] == 0) // child processes
{
printf("hello !\n");
}
else if (pid[0] >0)
{
parent_func(pid[0]);
}
/* section 2 */
for (i=0;i<n;i++)
{
pid[i] = fork();
if (pid[i] == 0) // child processes
{
child_func(shm);
}
else if (pid[i] >0)
{
parent_func(pid[i]);
}
}
printf("all done\n");
/* detach shm */
shmdt(shm);
/* destroy shm */
int retval = shmctl(shmid, IPC_RMID, NULL);
if (retval < 0) perror("remove shm");
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义第5行的数量
char*shm;
无效子函数(字符*shm)
{
while(atoi(shm)!=NUM_行)
{
//P(扫描电镜);
printf(“正在阅读单词:%d\n”,atoi(shm));
*shm+=1;
//V(扫描电镜);
}
出口(0);
}
无效父函数(pid\U t pid)
{
智力状态;
等待;
做
{
pid_wait=waitpid(pid和状态,WNOHANG);
}while(pid_wait!=pid);
//printf(“进程%d已完成\n”,getppid());
}
int main(int argc,char const*argv[]
{
/*声明*/
pid_t pid[8];
int ret、shmid、状态、尸体、i、ave、n;
char-fn[20];
键=123;
字符*字符串返回;
/*创建共享内存*/
如果((shmid=shmget(键,SHMSIZE,IPC|u CREAT | 666))0)
{
父函数(pid[0]);
}
/*第二节*/
对于(i=0;i0)
{
父函数(pid[i]);
}
}
printf(“全部完成”\n);
/*分离shm*/
shmdt(shm);
/*摧毁shm*/
int retval=shmctl(shmid,IPC_RMID,NULL);
如果(retval<0)perror(“移除shm”);
返回0;
}
在第一节中添加退出(0)后,我在最后一节中只得到一个“全部完成”,这就是我想要的答案
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/shm.h>
#include <string.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <errno.h>
#include <sys/wait.h>
#include <fcntl.h>
#define NUM_LINES 5
char * shm;
void child_func(char *shm)
{
while (atoi(shm) != NUM_LINES)
{
// P(sem);
printf("now reading word:%d\n", atoi(shm) );
*shm+=1;
// V(sem);
}
exit(0);
}
void parent_func(pid_t pid)
{
int status;
pid_t pid_wait;
do
{
pid_wait = waitpid(pid, &status, WNOHANG);
}while (pid_wait != pid);
// printf("Process %d done\n", getppid());
}
int main(int argc, char const *argv[])
{
/* declarations */
pid_t pid[8];
int ret, shmid, status,corpse, i, ave, n;
char fn[20];
key_t key = 123;
char *string_back;
/* create share memory */
if ((shmid = shmget(key, SHMSIZE, IPC_CREAT|666)) <0)
{
perror("shmget");
exit(1);
}
/* attach shm */
if ((shm = shmat(shmid, NULL, 0)) == (char*)-1)
{
perror("shmat");
exit(1);
}
/* init shm value */
*shm = '0';
/* input */
printf("please enter n:\n");
scanf("%d", &n);
/* section 1 */
pid[0] = fork();
if (pid[0] == 0) // child processes
{
printf("hello !\n");
/* problem solved here */
exit(0);
}
else if (pid[0] >0)
{
parent_func(pid[0]);
}
/* section 2 */
for (i=0;i<n;i++)
{
pid[i] = fork();
if (pid[i] == 0) // child processes
{
child_func(shm);
}
else if (pid[i] >0)
{
parent_func(pid[i]);
}
}
printf("all done\n");
/* detach shm */
shmdt(shm);
/* destroy shm */
int retval = shmctl(shmid, IPC_RMID, NULL);
if (retval < 0) perror("remove shm");
return 0;
}
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#定义第5行的数量
char*shm;
无效子函数(字符*shm)
{
while(atoi(shm)!=NUM_行)
{
//P(扫描电镜);
printf(“正在阅读单词:%d\n”,atoi(shm));
*shm+=1;
//V(扫描电镜);
}
出口(0);
}
无效父函数(pid\U t pid)
{
智力状态;
等待;
做
{
pid_wait=waitpid(pid和状态,WNOHANG);
}while(pid_wait!=pid);
//printf(“进程%d已完成\n”,getppid());
}
int main(int argc,char const*argv[]
{
/*声明*/
pid_t pid[8];
int ret、shmid、状态、尸体、i、ave、n;
char-fn[20];
键=123;
字符*字符串返回;
/*创建共享内存*/
如果((shmid=shmget(键,SHMSIZE,IPC|u CREAT | 666))0)
{
父函数(pid[0]);
}
/*第二节*/
对于(i=0;i0)
{
父函数(pid[i]);
}
}
printf(“全部完成”\n);
/*分离shm*/
shmdt(shm);
/*摧毁shm*/
int retval=shmctl(shmid,IPC_RMID,NULL);
如果(retval<0)perror(“移除shm”);
返回0;
}
第1节中的第一个子进程没有提前终止。好吧,我知道它可能不会提前终止,但为什么它会打印“全部完成”两次呢?第一个子进程将返回“全部完成”语句。无论父进程是否等待它,子进程都已经执行了“all done”语句,然后进程通过运行主函数的结尾正常结束。其他子级调用exit(0)
,因此它们提前终止,没有机会执行“all done”。第二条“全部完成”消息来自父进程,在所有子进程终止之后。(为了验证这一点:还要在“全部完成”、“您好”和“行读取”输出中打印PID。)好的,我知道了!非常感谢你!我的意思是,除非我设法误读了代码,否则共享内存内容的唯一赋值是*shm='\0'代码>因此其中有一个空字符串,因此atoi(shm)
将返回0。最后,如果使用共享内存进行进程间通信,则需要担心读写进程之间的同步,以确保一致地访问内存;但是,在短期内,除了父进程之外,没有任何进程正在写入共享内存,并且在创建子进程之前就已经写入了,因此(到目前为止)没有同步问题。