使用二进制信号量实现计数信号量

时间:2017-05-05 09:45:55

标签: c synchronization thread-safety semaphore binary-semaphore

我已经实现了一些用户级线程系统。我需要一些帮助来实现计数信号量,使用二进制信号量 实现(上下功能如下所述)。 这是我实现二进制信号量的接口:

typedef enum BinSemStatus{
   locked,
   unlocked
} BinSemStatus;


struct semaphore {
BinSemStatus status;
int bid;
};

int bsem_alloc();//allocate a new binary semaphore,return its descriptor
void bsem_free(int id);
void bsem_down(int id);
void bsem_up(int id);

这是计数信号量接口的接口:

struct counting_semaphore* counting_alloc(uint value);
counting_free(struct counting_semaphore* sem);

// If the value representing the count of
// the semaphore variable is not negative, decrement it by 1. If the 
// semaphore variable is now
// negative, the thread executing acquire is blocked until the value is 
// greater or equal to 1.
// Otherwise, the thread continues execution.
void up(struct counting_semaphore* sem);
// Increments the value of semaphore
// variable by 1.
void down(struct counting_semaphore* sem);

我试图做的是虚空(struct counting_semaphore * sem) 锁定价值。但正如你在下面看到的那样还不够。我在有问题的情况下添加了评论。

struct counting_semaphore {
int binary_descriptor;
int value;
}; 

void down(struct counting_semaphore *sem){
  bsem_down(sem->binary_descriptor);
  if (sem->value > 0){
    sem->value--;
  }
  else{
     //not sure what to do here, maybe use anather semaphore in some way?
  } 
  bsem_up(sem->binary_descriptor);
 }
void up(struct counting_semaphore *sem){
  bsem_down(sem->binary_descriptor);
  sem->value++;
  bsem_up(sem->binary_descriptor);
}

2 个答案:

答案 0 :(得分:0)

sem->value达到0时,线程会阻塞,现在是时候重新安排了。你没有显示你的日程安排代码,所以我不能给出具体的建议。调度程序可能应代表线程调用bsem_up(sem->binary_descriptor);

答案 1 :(得分:0)

关键部分由sem-> binary_descriptor1保护,每个操作down(S)和up(S)使用它来正确更新sem.value的值 更新两个操作后,仅在值为正时才释放sem-> binary_descriptor2信号量 S.value永远不会为负,因为执行down(S)的任何进程都会在sem-> binary_descriptor2处被阻塞。

  struct counting_semaphore* counting_semaphore_alloc(int value) {

    struct counting_semaphore* sem = malloc(sizeof(struct counting_semaphore));
    sem->value = value;
    sem->binary_descriptor1= bsem_alloc();//locks the value
    sem->binary_descriptor2= bsem_alloc();//locks the sing of the value
    if (value <= 0) {
        bsem_down(sem->binary_descriptor2);
    }
    return sem;
    }

void down(struct counting_semaphore *sem){
    bsem_down(sem->binary_descriptor2);
    bsem_down(sem->binary_descriptor1);
    sem->value--;
    if (sem->value>0){
        bsem_up(sem->binary_descriptor2);
    }
    bsem_up(sem->binary_descriptor1);
}


void up(struct counting_semaphore* sem) {
    bsem_down(sem->binary_descriptor1);
    sem->value++;
    if (sem->value == 1) {
        bsem_up(sem->binary_descriptor2);
    }
    bsem_up(sem->binary_descriptor1);
}