如何在 linux 上的两个进程之间共享内存的情况下在 c 中使用 posix 命名信号量?

how to use posix named semaphore in c with shared memory between two processes on linux?

我正在尝试同步两个进程以读取和写入共享内存。这里是 a_process.c:

 #include <fcntl.h>
 #include <sys/mman.h>
 #include <semaphore.h>
 #include <sys/stat.h>
 #include <unistd.h>
 #include <stdlib.h>
 #include <errno.h>
 #include <stdio.h>

 #define SHM_PATH        "/instant_messaging"
 #define SHM_SIZE         50
 #define SEM_PATH        "/sem_instant_messaging"

 char *sendbuff;

 int main()
 {
     //sahred memory setting 
     //shm_unlink(SHM_PATH);
     int shmfd;

     shmfd = shm_open(SHM_PATH, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);
     if (shmfd < 0) {
         perror("In shm_open()");
         exit(1);
     }

     int shm_size = SHM_SIZE;

     ftruncate(shmfd, shm_size); 
     sendbuff = (char*) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, 
             MAP_SHARED, shmfd, 0);
     if (sendbuff == NULL) {
        perror("In mmap()");
        exit(1);
     }

     //semaphore setting 
     sem_unlink(SEM_PATH);

     sem_t * sem1;

     sem1 = sem_open(SEM_PATH, O_CREAT, S_IRUSR | S_IWUSR, 1);
     printf("before while\n");
     //setmemshr();
     //setsem();
     while (1) {
         int status = sem_wait(sem1);

         if (status != 0)
         {
             perror("in sem_wait");
         }
         printf("after wait\n");
         printf("%s\n",sendbuff);
         scanf("%s",sendbuff);
         sem_post(sem1);
         //sleep(3);
     }
 }

这里是 b_process.c:

#include <fcntl.h>
#include <sys/mman.h>
#include <semaphore.h>
#include <sys/stat.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <stdio.h>

#define SHM_PATH        "/instant_messaging"
#define SHM_SIZE         50
#define SEM_PATH        "/sem_instant_messaging"  //dddddddddd

char *sendbuff;

int main()
{
    //sahred memory setting
    //shm_unlink(SHM_PATH); 
    int shmfd;

    shmfd = shm_open(SHM_PATH, O_CREAT | O_RDWR, S_IRWXU | S_IRWXG);
    if (shmfd < 0) {
        perror("In shm_open()");
        exit(1);
    }

    int shm_size = SHM_SIZE;

    ftruncate(shmfd,shm_size);
    sendbuff = (char*) mmap(NULL, shm_size, PROT_READ | PROT_WRITE, 
            MAP_SHARED, shmfd, 0);
    if (sendbuff == NULL) {
        perror("In mmap()");
        exit(1);
    }

    //semaphore setting 
    sem_unlink(SEM_PATH);

    sem_t *sem1;

    sem1 = sem_open(SEM_PATH, O_CREAT, S_IRUSR | S_IWUSR, 1);   

    while (1) {
        printf("before wait %d\n", *sem1);
        int status = sem_wait(sem1);

        if (status != 0)
        {
            perror("in sem_wait");
        }
        printf("after wait %d\n", *sem1);
        printf("%s", sendbuff);
        scanf("%s", sendbuff);
        sem_post(sem1);
    }
}

我花了很多时间调试这个和阅读手册页,但似乎虽然共享内存有效,信号量 post 和等待在每个进程的地址 space 内工作,但这两个进程任何一个都不要影响另一个在共享内存区域中看到的数据。

有人看到我遗漏了什么吗?

您的代码中有一些可疑的地方,但有一种组合明显是错误的:两个进程都执行 sem_unlink(),紧接着在信号量路径上执行 sem_open() .这可能会产生两个过程使用相同信号量的效果,只有当你非常幸运时,这样两个 sem_unlink()s 都在 sem_open() 执行之前执行。否则,无论哪个进程在后,都将取消链接第一个创建的信号量,而是创建并使用它自己的信号量。两个进程都将继续,每个进程都使用自己独立的信号量。

我还发现这两个进程 ftruncate() 共享内存区域有点可疑,尤其是它们在同步之前这样做(或者如果进程完全有效地同步的话它们会这样做)。我认为你应该让一个进程负责设置共享内存段;另一个只需要打开并映射它。更正您的信号量初始化,并使用信号量确保共享内存在任一程序继续使用它之前确定大小。