C中的进程同步不会第一次执行

C中的进程同步不会第一次执行,c,process,fork,semaphore,synchronisation,C,Process,Fork,Semaphore,Synchronisation,所以我在C中的进程同步程序中遇到了这个问题 我应该使用fork(),生成这样的代码: PARENT PARENT CHILD PARENT CHILD PARENT 使用我找到的一个代码,我能够使它工作,但由于某些原因,屏幕上出现的第一个结果是混乱的,而所有其他的工作都很好 要编译,请键入:gcc test.c display.c-o test-pthread 无论如何,下面是我正在测试的代码(我重复:这不是我的代码): 为什么在开始时会发生这种情况?您不能编写一个程序,用一个信号量在父进程和

所以我在C中的进程同步程序中遇到了这个问题

我应该使用
fork()
,生成这样的代码:

PARENT
PARENT
CHILD
PARENT
CHILD
PARENT
使用我找到的一个代码,我能够使它工作,但由于某些原因,屏幕上出现的第一个结果是混乱的,而所有其他的工作都很好

要编译,请键入:
gcc test.c display.c-o test-pthread

无论如何,下面是我正在测试的代码(我重复:这不是我的代码):


为什么在开始时会发生这种情况?

您不能编写一个程序,用一个信号量在父进程和子进程之间交替运行(不使用某种形式的忙等待标志或其他东西),因为两个进程都会竞相获取信号量;没有办法预测哪个进程将首先获得它。您的代码(第一次迭代除外)似乎按预期工作,因为孩子睡了很长时间,但从技术上讲,这仍然是一种竞争条件,不能保证家长有机会在孩子醒来之前获得信号量(尽管可能性很小)

因此,您需要两个信号量:一个用于孩子通知家长该轮到他了,另一个用于家长通知孩子。要选择谁先启动,请将相应的信号量初始化为1(另一个初始化为0)

而且,这是错误的:

sem_t *sema = mmap(NULL, sizeof(sema), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);
第二个参数应该是
sizeof(*sema)
,因为您希望为信号量对象而不是指针分配内存

您永远不会包含“display.h”,您可能应该这样做

错误处理是可以改进的,但是对于这个玩具程序,我不认为这是一个大问题

下面是一个使用2信号量方法的工作版本(这将父信号量初始化为1,因此父信号量将首先启动):

#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
#包括
内部主(空)
{
int i;
/*将信号量放在共享内存中*/
sem|t*child|sem=mmap(NULL,sizeof(*child|sem),PROT|u READ | PROT|u WRITE,MAP|u SHARED | MAP|u ANONYMOUS,-1,0);
sem|t*parent|sem=mmap(NULL,sizeof(*parent|sem),PROT|u READ | PROT|u WRITE,MAP|u SHARED | MAP|u ANONYMOUS,-1,0);
/*创建/初始化信号量*/
if(sem_init(child_sem,1,0)<0)
{
perror(“sem_init”);
退出(退出失败);
}
if(sem_init(parent_sem,1,1)<0){
perror(“sem_init”);
退出(退出失败);
}
int nloop=10;
int-pid=fork();
如果(pid==0)
{
对于(i=0;i
为了简洁起见,我删除了
munmap(2)
sem\u destroy(3)
调用,因为它们是不必要的,因为进程正在退出

请注意,这两个进程遵循相同的模式:等待它们的信号量,执行工作,通知另一个进程的信号量。这是一个很好的机会,可以进行一些重构,并将其全部移动到一个函数,该函数接收要显示的字符串、要等待的信号量以及随后要通知的信号量


您还应该习惯于使用
-Wall

进行编译,并在头脑中逐步完成代码。父级和子级都立即打印,没有任何同步。因为您在信号量操作之前调用了
display
。好的,非常感谢,伙计,它在我脑子里整理了很多东西。
PACREHNT
ILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
PARENT
CHILD
sem_t *sema = mmap(NULL, sizeof(sema), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);
#include <semaphore.h>
#include <stdio.h>
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <sys/mman.h>

int main(void)
{
    int i;
    /* place semaphore in shared memory */
    sem_t *child_sem = mmap(NULL, sizeof(*child_sem), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);
    sem_t *parent_sem = mmap(NULL, sizeof(*parent_sem), PROT_READ |PROT_WRITE,MAP_SHARED|MAP_ANONYMOUS,-1, 0);

    /* create/initialize semaphore */
    if ( sem_init(child_sem, 1, 0) < 0)
    {
        perror("sem_init");
        exit(EXIT_FAILURE);
    }

    if (sem_init(parent_sem, 1, 1) < 0) {
        perror("sem_init");
        exit(EXIT_FAILURE);
    }

    int nloop=10;
    int pid = fork();
    if (pid == 0)
    {
        for (i = 0; i < nloop; i++)
        {
            if (sem_wait(child_sem) < 0)
                perror("sem_wait");
            display("CHILD\n");
            if (sem_post(parent_sem) < 0)
                perror("sem_post");
            sleep(1);
        }
    }
    else
    {
        for (i = 0; i < nloop; i++)
        { // parent starts waiting
            if (sem_wait(parent_sem) < 0) 
                perror("sem_wait");
            display("PARENT\n");
            if (sem_post(child_sem) < 0)
                perror("sem_post");
        }
    }
}