彼得森关键部分问题的解决方案

时间:2010-08-13 05:24:23

标签: c

#include<stdio.h>
#include<sys/types.h>
#include<stdlib.h>
int turn;
int flag[2];
int main(void)
{
        int pid,parent=1;
        printf("before vfork\n");
        if((pid=vfork())<0)
        {
                perror("vfork error\n");
                return 1;

        }
        while(1)
        {
                if(pid==0)
                {
                     while(parent==1)
                     {
                      sleep(2);
                     }
                     parent=0;
                     flag[0]=1;
                     turn=1;
                     while(flag[1]&&turn==1);
                     printf("This is critical section:parent process\n");
                     flag[0]=0;
                }
                else
                {
                        parent=2;
                        printf("This is parent");
                        flag[1]=1;
                        turn=0;
                        while(flag[0]&&turn==0);
                        printf("This is critical section:child process %d \n",pid);
                        flag[1]=0;
                }
        }

}

这是我的代码。任何人都可以说出为什么控制不会进入我的父进程。

5 个答案:

答案 0 :(得分:3)

man 2 vfork说:

   (From  POSIX.1)  The  vfork()  function has the same effect as fork(2),
   except that the behavior is undefined if the process created by vfork()
   either  modifies  any  data other than a variable of type pid_t used to
   store the return value from vfork(), or returns from  the  function  in
   which  vfork()  was called, or calls any other function before success-
   fully calling _exit(2) or one of the exec(3) family of functions.

因为您正在修改子进程中的数据,vfork()行为是未定义的,所以无论它做什么都是正确的(这里“正确”我的意思是“符合规范”)。

答案 1 :(得分:1)

因为,父级的整个虚拟地址空间在子级中已复制。 所以两个进程有不同的地址空间。并且标志[1]在父进程中永远不会变为1。

答案 2 :(得分:1)

vfork()旨在使用execve():vfork()+ immediate execve()快速创建进程。在子项修改父进程的任何数据的情况下,行为未定义。检查一下人的细节。

就我而言,这种行为使父母只有在孩子关闭后才能达到控制。

答案 3 :(得分:1)

这是Linux手册页中的重要部分。关键字:“父级被暂停,直到孩子 ...”

    vfork()  differs from fork(2) in that the parent is suspended until the
    child makes a call to execve(2) or _exit(2).  The child shares all mem-
    ory  with its parent, including the stack, until execve(2) is issued by
    the child.  The child must not return from the current function or call
    exit(3), but may call _exit(2).

您的父进程已被暂停。考虑使用clone

答案 4 :(得分:0)

此代码不保证公平;它只能防止死锁。

没有什么可以阻止子进程一次又一次地执行。

如果你想要锁定公平,你就必须这样做。