【问题标题】:Semaphore deadlock when using unnamed semaphores in POSIX with shared memory在具有共享内存的 POSIX 中使用未命名信号量时出现信号量死锁
【发布时间】:2021-04-24 11:59:20
【问题描述】:

我有 2 个信号量。我有一个共享内存段。我正在尝试同步进程,以便它们相互等待,直到某个任务完成,但是当 sem_post_util(sem_sync) 在其他进程中使用时就会停止,最后一个进程继续并退出。为什么不增加共享内存中未命名的信号量?

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "../../utils.h"
#include <signal.h>

#define SHARED_MEM "/shmm115"
#define SEM "nammed_sem115"
#define SEM_SYNC "unnamed_sem115"
#define SIZE 256
#define n_proc 3

sem_t *sem, sem_sync;
void* addr;

void cleanup(){
    sem_close( sem );
    sem_close( &sem_sync );
    munmap_util( addr, SIZE );
    shm_unlink( SHARED_MEM );
}

int main(){
    sem = sem_open( SEM, O_CREAT, 0666, 1 );/*opent the named semaphore we got*/

    /*Open shared memory segment and put a shared variable inside of it*/
    struct sigaction handler;
    handler.sa_handler = cleanup;

    sigaction( SIGINT, &handler, NULL);

    int fd;
    short count = 0;
    fd  = shm_open_util(SHARED_MEM, O_RDWR | O_CREAT, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH | S_IRWXU);

    struct stat stat_buf;
    fstat( fd, &stat_buf );
    if( stat_buf.st_size == 0){/*if it is the first one to write to it*/
        ftruncate_util(fd, SIZE);
        addr = mmap_util(0, SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);
        memcpy( addr, &count, sizeof(short) );
        memcpy( addr+sizeof(short), &sem_sync, sizeof(sem_t) );
    }
    else
        addr = mmap_util(0, SIZE, PROT_WRITE | PROT_READ, MAP_SHARED, fd, 0);

    close(fd);
    
    sem_init_util( &sem_sync, 1, 0 );

    sem_wait_util( sem );
    printf("Reading count\n");
    memcpy(&count, addr, sizeof(short));
    printf("Incrementing and writing the count: %d\n", count);
    count++;
    memcpy(addr, &count, sizeof(short));
    sem_post_util( sem );

    if( count == n_proc ){
        printf("%d unblocks all the processes\n", getpid());
        for( int i = 0 ; i<n_proc-1; ++i )
            sem_post_util( addr + sizeof(short) );
    }
    else{
        printf("%d pauses\n", getpid());
        sem_wait_util( &sem_sync );
    }

    printf("%d continues\n", getpid());
    sem_close( sem );
    sem_close( &sem_sync );
    munmap_util( addr, SIZE );
    shm_unlink( SHARED_MEM );
}

我使用 ./a.out & ./a.out & ./a.out

运行它

这是输出

[70] 19882
[71] 19883
Reading count
Incrementing and writing the count: 0
19882 pauses
Reading count
Incrementing and writing the count: 1
19883 pauses
Reading count
Incrementing and writing the count: 2
19884 unblocks all the processes
19884 continues

如您所见,只有最后一个进程继续,进程 19882 和 19883 没有继续并挂在那里等待。我做错了什么?

我希望信号量与其中的一些其他数据一起位于共享内存中。

【问题讨论】:

    标签: c posix semaphore shared-memory systems-programming


    【解决方案1】:

    您没有将源代码提供给 util.h,但您似乎是通过 sem_wait_util( &amp;sem_sync ); 获取信号量,但通过 sem_post_util( addr + sizeof(short) ); 释放它。

    我原以为它会通过sem_post_util(&amp;sem_sync);发布

    【讨论】:

      【解决方案2】:

      对 POSIX 信号量副本的操作未定义。您必须在sem_initsem_open 初始化的内存上postwait

      因此,sem_sync 中的 memcpy 在普通进程内存中初始化为共享内存不会使该内存成为可行的信号量。

      请尝试以下方法:

      struct shared_items {
        sem_t sem;
        short count;
      } *shmem;
      
      ....
      
      *shmem = mmap(0, sizeof(*shared_bundle), ..., shm_opened_fd, 0);
      
      if (i_am_the_first_to_open_this_shared_memory) {
        sem_init(&shmem->sem, 1, 0);
      }
      
      ....
      
      sem_post(&shmem->sem);
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-19
        • 2020-09-01
        • 2016-11-01
        • 2010-10-26
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多