共享内存使用信号量保护写入

时间:2013-07-19 14:29:41

标签: c linux ipc shared-memory semaphore

下面的服务器代码,其中一个字符串变为共享内存变量。

客户端代码显示共享内存中可用的字符串。

完整代码:available in this github link

Server.c

int main(int argc, char *argv[])
{
    /* code to create posix shared memory and posix named semaphore */

    /* critical section start */

    snprintf(shared_msg->content, MAX_MSG_LENGTH, "%s", argv[1]);

    /* critical section end */
}

Client.c

int main(int argc, char *argv[])
{
    /* code to open posix shared memory and posix named semaphore */

    for(i=0; i<20; i++){
        /* critical section start */

       //operation of semaphore
        while(loop < 15){
            printf("Type : %d, content : %s\n", shared_msg->type, shared_msg->content);
            sleep(1);
            loop++;
        }

     /* Critical section end */

    loop = 0;
    printf("loop %d finished\n", i);
      }
}

如何在上面的代码中使用(等待和发布)POSIX信号量,以实现以下要求

  • 当客户端启动时,它必须显示共享内存数据。一旦内部while循环完成,那么只有客户端释放共享内存。
  • 如果服务器启动并尝试将数据写入共享内存,当客户端while循环运行时,信号量将不会写入允许写入,直到客户端释放信号量。
  • 单行服务器必须在客户端发布信号量时编写

感谢。

2 个答案:

答案 0 :(得分:1)

您需要准互斥或二进制信号量,即一次只有一个进程可以访问资源,在这种情况下是共享内存。所以这看起来不对:

mysem = sem_open(SEMOBJ_PATH, O_CREAT | O_EXCL | O_RDWR, S_IRWXU | S_IRWXG, 2);

您希望初始值为1.第一个想要写入共享内存的进程调用sem_wait将ctr递减为0,从而强制调用sem_wait的任何其他进程等到值为非零。换句话说,信号量被锁定,直到持有它的进程执行sem_post

您的伪代码看起来基本正确。当您输入关键部分时sem_wait,当您退出时sem_post。根据我的理解,我认为您的问题在于错误地初始化sem_open上的信号量。

答案 1 :(得分:0)

从@Duck的回答我重写代码。现在我得到了预期的输出。

我在@Duck回答

中用1初始化信号量

更新了server.c

int main(int argc, char *argv[])
{
  /* code to create posix shared memory and posix named semaphore */

  /* critical section start */
  sem_wait(mysem); //update
  snprintf(shared_msg->content, MAX_MSG_LENGTH, "%s", argv[1]);

  /* critical section end */
}

更新了client.c

int main(int argc, char *argv[])
{
/* code to open posix shared memory and posix named semaphore */

for(i=0; i<20; i++){
    /* critical section start */

   //operation of semaphore
    while(loop < 15){
        printf("Type : %d, content : %s\n", shared_msg->type, shared_msg->content);
        sleep(1);
        loop++;
    }
    sem_post(mysem);
 /* Critical section end */

    loop = 0;
    printf("loop %d finished\n", i);
   }
}