程序陷入while循环

Program stuck in while loop

我试图在 while 循环中使用信号量,但我的程序 运行 处于无限循环中。基本上我 fork off children 并使用 execv 来启动新的用户进程。进程使用共享内存中的信号量进行通信。

struct shared
{
int count;
sem_t sem;
} *shmem;
void forking()
{
key_t shmkey = ftok("makefile",777);
        if (shmkey == -1) {
            perror("Ftok failed");
            exit(-1);
        }

        // Get our shm id
        shmid = shmget(shmkey, sizeof(shared), 0666 | IPC_CREAT);
        if (shmid == -1) {
            perror("Failed to allocate shared memory region");
            exit(-1);
        }

        // Attach to our shared memory
        shmem = (shared*)shmat(shmid, (void *)0, 0);
        if (shmem == (void *)-1) {
            perror("Failed to attach to shared memory region");
            exit(-1);
        }

    sem_init(&(shmem->sem),1,1);
    pid_t PID;
    int i;
    for(i=0;i<4;i++)
    {
    PID=fork();
    if(PID==0)
    {
        static char *args[]={"./child",NULL};
        int status;
        if(( status= (execv(args[0], args)))==-1)
        perror("failed to execv");
        exit(EXIT_FAILURE);
    }
    if(PID>0)
    {
        while(1)
        {
            sem_wait(&(shmem->sem));
            {
                shmem->count=shmem->count+1;
            }
            sem_post(&(shmem->sem));
        }
    }
    if(PID<0)
    perror("error in fork");
    }
}
main()
{
    forking();
}

在child.c

struct shared
{
int count;
sem_t sem;
} shmem;
void main()
{
    bool alive=true;
    do
    {
    sem_wait(&(shmem->sem));
    if(shmem->count==5)
    {
        shmem->count=0; 
        alive=false;
    }
    sem_post(&(shmem->sem));
    }while(alive);
}

child.c 无休止地循环,不允许父级将 i 递增到 5。即使我在第一个文件中注释掉 while 循环并让它在没有 loops.In 的情况下递增,也会发生这种情况。结束没有任何退出。

你用错了fork,绝对不是用共享内存。

这里有几点

  1. 通过调用 fork,您将在不同的内存 space 中复制 parent 运行。 http://man7.org/linux/man-pages/man2/fork.2.html
  2. 通过使用 execve,您实际上删除了旧内存并将其替换为新内存,而新内存无论如何都没有链接到您的 parent 进程。 http://man7.org/linux/man-pages/man2/execve.2.html

为了让你的代码工作,你应该使用 pthread_* 而不是因为它将存在于相同的内存中 space 并使你的全局变量 volatile 因为 gcc 将尝试优化并且会有奇怪的行为如果这样做的话。

好吧,我似乎错过了很多要点,但我的假设并非完全错误。

所以你的 child.c 少了很多代码

  1. 它不包含您在 parent 中所做的所有初始化,这是必要的,因为如果您使用 execve,您基本上会丢失之前在 [=] 中映射的所有内存映射45=]进程。
  2. 你的 parents 无限循环所以 shmem->count 永远不会真正等于 5,你将不得不在某个时刻中断或改变你的 child 代码中的条件。

这是您的 child 的样子。

#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>

typedef struct
{
    int count;
    sem_t sem;
} shared;

shared *shmem;
int shmid;
key_t shmkey;

int main()
{
    int alive=1;

    shmkey = ftok("makefile",777);
    if (shmkey == -1) {
        perror("Ftok failed");
        exit(-1);
    }

    // Get our shm id
    shmid = shmget(shmkey, sizeof *shmem, 0);
    if (shmid == -1) {
        perror("Failed to allocate shared memory region");
        exit(-1);
    }

    // Attach to our shared memory
    shmem = (shared*)shmat(shmid, (void *)0, 0);
    if (shmem == (shared *)-1) {
        perror("Failed to attach to shared memory region");
        exit(-1);
    }

    do
    {
        sem_wait(&(shmem->sem));
        printf("%d\n", shmem->count);
        if(shmem->count > 5)
        {
            shmem->count=0; 
            alive=0;
        }
        sem_post(&(shmem->sem));
    }while(alive);

    printf("I have finished %u\n", getpid());
    exit(0);
}