Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/powerbi/2.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 程序卡在while循环中_C_While Loop_Semaphore - Fatal编程技术网

C 程序卡在while循环中

C 程序卡在while循环中,c,while-loop,semaphore,C,While Loop,Semaphore,我试图在while循环中使用信号量,而我的程序正在无限循环中运行。基本上,我放弃子进程,使用execv启动新的用户进程。进程使用共享内存中的信号量进行通信 struct shared { int count; sem_t sem; } *shmem; void forking() { key_t shmkey = ftok("makefile",777); if (shmkey == -1) { perror("Ftok failed");

我试图在while循环中使用信号量,而我的程序正在无限循环中运行。基本上,我放弃子进程,使用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();
}
c无休止地循环,不允许父级将i递增到5。即使我在第一个文件中注释掉while loop并让它在没有循环的情况下递增,也会发生这种情况。最后什么都不存在。

您使用fork时出错了,而且肯定没有使用共享内存

这里有几点

  • 通过调用fork,您正在创建在不同内存空间中运行的父级的副本
  • 通过使用execve,您基本上删除了旧内存,并将其替换为新内存,而新内存无论如何都不会链接到父进程 为了使代码正常工作,您应该使用
    pthread.*
    ,因为它将位于相同的内存空间中,并使您的全局变量不稳定,因为gcc将尝试进行优化,如果这样做,则会出现奇怪的行为

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

    因此,您的child.c缺少很多代码

  • 它不包含您在父进程中进行的所有必要初始化,因为如果您使用
    execve
    ,您实际上会丢失以前在父进程中映射的所有内存映射
  • 您的父母无限循环,因此
    shmem->count
    永远不会真正等于5,您必须在某个时刻中断或更改子代码中的条件 你的孩子应该是这样的

    #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);
    }
    
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    #包括
    类型定义结构
    {
    整数计数;
    扫描电镜;
    }共享;
    共享*shmem;
    int shmid;
    钥匙;
    int main()
    {
    int-alive=1;
    shmkey=ftok(“makefile”,777);
    如果(shmkey==-1){
    perror(“Ftok失败”);
    出口(-1);
    }
    //获取我们的shm id
    shmid=shmget(shmkey,sizeof*shmem,0);
    如果(shmid==-1){
    perror(“分配共享内存区域失败”);
    出口(-1);
    }
    //依附于我们共享的记忆
    shmem=(共享*)shmat(shmid,(void*)0,0;
    如果(shmem==(共享*)-1){
    perror(“未能连接到共享内存区域”);
    出口(-1);
    }
    做
    {
    sem_wait(&(shmem->sem));
    printf(“%d\n”,shmem->count);
    如果(shmem->count>5)
    {
    shmem->count=0;
    活着=0;
    }
    sem_post(&(shmem->sem));
    }活着的时候;
    printf(“我已经完成了%u\n”,getpid());
    出口(0);
    }
    
    结构共享{int count;sem\u t sem;};共享shmem是一个错误。您缺少一个
    typedef
    struct
    。实际上,我使用了一个单独的文件作为结构,并将其包含在两个程序中。但是现在我想它很好。
    shared->count
    的名字不好。它不在父级和子级之间共享。父进程正在其自己的进程空间中递增计数器。每个子进程都在检查其进程空间中变量的值。很抱歉,忘记添加共享数据初始化。在第一个文件中没有任何内容可以脱离
    ,而(1)
    ,没有任何标志或条件可以中断或计算为false…我们的类尚未达到pthread,你能修改我的程序来告诉我pthread是如何工作的吗?好吧,看来我没有注意到信号量,它应该在另一个进程中工作,但不是在execve之后,让我修复它,我还将发布一个代码workingEdit:我修复了我的答案@Fairy
    #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);
    }