Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/hadoop/6.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 与分叉过程混淆?_C_Multiprocessing - Fatal编程技术网

C 与分叉过程混淆?

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

我正在尝试执行第一个子函数,例如,打印一个字符串:hello!,然后返回到父进程。然后,我为第二个子函数分叉了另一个n进程,它将计算共享内存数。我想最后只显示了一个“全部完成”,但它显示了两个?谢谢你的帮助

#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。最后,如果使用共享内存进行进程间通信,则需要担心读写进程之间的同步,以确保一致地访问内存;但是,在短期内,除了父进程之外,没有任何进程正在写入共享内存,并且在创建子进程之前就已经写入了,因此(到目前为止)没有同步问题。