【问题标题】:Issue with the semaphore locking in the shared memory共享内存中的信号量锁定问题
【发布时间】:2013-09-23 18:11:40
【问题描述】:
#include <stdio.h>
#include <fcntl.h>
#include <string.h>
#include <unistd.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>

int main()
{
  key_t key, k, shmid;
  int ret, semid, i = 0;
  struct sembuf op[1];
  void *shmptr = (void *) 0;

  union semun {
    int val;
    struct senid_ds *buf;
    unsigned short *array;
  };

  union semun arg;

  /* Creating a shared memory */
  k = ftok(".", 1);

  if (-1 == k) {
    perror("\n ftok \n");
    return 1;
  }

  shmid = shmget(k, 1000, IPC_CREAT | 0744);

  if (-1 == shmid) {
    perror("\n Shared memory creation failed \n");
    return 2;
  }

  shmptr = shmat(shmid, (void *) 0, 0);

  if (NULL == shmptr) {
    perror("\n Process cant attach to shared memory segment! \n");
    return 3;
  }

  /* Creating semaphore */
  key = ftok(".", 4);

  if (-1 == key) {
    perror("\n ftok \n");
    return 4;
  }

#if 0
  semid = semget(key, 1, IPC_CREAT);
#else
  semid = semget(key, 1, 0);
#endif

  if (-1 == semid) {
    perror("\n Cannot create semaphore \n");
    return 5;
  }

#if 0
  arg.val = 1;
  ret = semctl(semid, 0, SETVAL, arg);
  printf("\n ret : %d \n", ret);
#endif

  op[0].sem_num = 0;
  op[0].sem_op = -1;
  op[0].sem_flg = SEM_UNDO;

  ret = semop(semid, op, 1);

  // printf("\n ret : %d semop : %d\n",ret,op[0].sem);
  printf("\n Process 1 locked sem1 \n");

  /* Do Operation on shared resource */
  while (i < 4) {
    strcpy((char*) shmptr, "BDC");
    printf("\n %s \n", (char *) shmptr);
    sleep(2);
    printf("\n After sleep \n");
    i++;
    shmptr++;
  }

  op[0].sem_op = 1;
  ret = semop(semid, op, 1);
  printf("\n Process A unlocked sem1 \n");

  return 0;
}

我尝试了一个示例程序来锁定共享内存段。我尝试了同一程序的 2 个实例。查看信号量是否正确锁定。但是上面的程序总是允许其他进程在 process1 已经锁定的情况下使用共享内存。无法确定错误在哪里。

【问题讨论】:

  • 你看到了什么让你断定它不起作用?你做了什么来试图找到错误?
  • 代码中必须是Yoda Conditions
  • @wallyk : 2 个进程没有同步访问共享段

标签: c unix


【解决方案1】:

您应该启用IPC_CREAT 语句并按位或在第三个参数中添加必要但缺少的权限(至少是S_IRWXU)。

您应该启用SETVAL 语句以将信号量初始化为 1,但仅根据外部输入执行该语句(即,使用导致其创建信号量并对其进行初始化的参数调用程序);否则,程序应该假定信号量已经存在。

您需要检查semop() 调用的返回值。

【讨论】:

  • 谢谢史蒂夫。在创建时更改权限后,我也更改了键值。它奏效了。
猜你喜欢
  • 1970-01-01
  • 2010-11-27
  • 1970-01-01
  • 1970-01-01
  • 2010-12-03
  • 2010-10-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多