-2

我正在尝试实现一个涉及同步的真实世界模拟,当我有一个有 80% 机会发生的事件时,我目前正在做

  while((rand()%10)<8){
    up(sCar);
    printf("SOUTH: new car\n");
  }

但是,while 循环永远不会在运行时触发,所以我不确定我是否正确使用了 rand()。如果我将 rand() 替换为 7,则它工作正常。我目前设置

  srand (time(NULL));

在我的程序的早期也是如此。任何帮助将非常感激。

编辑:这是完整的运行程序。我修改了 sys.c 来创建 up 和 down 的系统调用,它们充当信号量。

#include <linux/unistd.h>
#include <stdio.h>
#include <sys/mman.h>
#include <stdlib.h>
#include <time.h>

struct cs1550_sem{
    int value;
    struct listnode *start;
    struct listnode *finish;
};

void up(struct cs1550_sem *sem) {
  syscall(__NR_cs1550_up, sem);
}

void down(struct cs1550_sem *sem) {
  syscall(__NR_cs1550_down, sem);
}

int main(void){

  srand (time(NULL));
  void * ptr = mmap(NULL, sizeof(struct cs1550_sem)*3, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);

  struct cs1550_sem *nCar = ((struct cs1550_sem *)ptr);
  struct cs1550_sem *sCar = ((struct cs1550_sem *)ptr) + 1;
  struct cs1550_sem *mutex = ((struct cs1550_sem *)ptr) + 2;
  struct cs1550_sem *flag = ((struct cs1550_sem *)ptr) + 3;

  void * northRoad = mmap(NULL, sizeof(int)*(10+1), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);
  void * southRoad = mmap(NULL, sizeof(int)*(10+1), PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);

  nCar->value  = 0;
  nCar->start= NULL;
  nCar->finish    = NULL;

  sCar->value  = 0;
  sCar->start= NULL;
  sCar->finish  = NULL;

  flag->value  = 0;
  flag->start= NULL;
  flag->finish    = NULL;

  mutex->value  = 1;
  mutex->start= NULL;
  mutex->finish  = NULL;


  if(fork()==0){
    while(1){
      while((rand()%10)<8){
        up(nCar);
        printf("NORTH: new car\n");
      }
      printf("NORTH: no more cars, sleeping for 20 seconds\n");
      sleep(20);
    }
  }
  else if(fork()==0){
    while(1){
      while((rand()%10)<8){
        up(sCar);
        printf("SOUTH: new car\n");
      }
      printf("SOUTH: no more cars, sleeping for 20 seconds\n");
      sleep(20);
    }
  }
  else if(fork()==0){ 
    while(1){
      down(nCar);
      down(mutex); 
      printf("NORTH car allowed through\n");
      up(mutex);
    }
  }
  else{
    while(1){
      down(sCar);
      down(mutex);
      printf("SOUTH car allowed through\n");
      up(mutex);
    }
  }
  return 0;
}
4

1 回答 1

0

我一直使用这个公式来获得有偏的 rand()。我相信这比取模方法得到更均匀的分布。

#define RAND_PCT_THRESHOLD(x)  (int)(((long)(x) * RAND_MAX) / 100))

if (rand() <  RAND_PCT_THRESHOLD(80))
{
  // ...
)

你是什​​么意思

我修改了 sys.c 来创建 up 和 down 的系统调用,它们充当信号量。

我不认为这是一个很好的主意。您确定没有比修改运行时库更简单、更安全的方法来执行原子增量吗?您的错误可能来自那里,因为您发布的代码的逻辑看起来确实正确,并且如果您没有弄乱read-only-unless-there-is-a-bug-in-it运行时可能会运行良好图书馆。

当您为“信号量”分配内存时:

 void * ptr = mmap(NULL, sizeof(struct cs1550_sem)*3, PROT_READ|PROT_WRITE, MAP_SHARED|MAP_ANONYMOUS, 0, 0);

您为 3 个信号量分配空间,而您显然需要为其中 4 个信号量分配空间。

  struct cs1550_sem *nCar = ((struct cs1550_sem *)ptr);
  struct cs1550_sem *sCar = ((struct cs1550_sem *)ptr) + 1;
  struct cs1550_sem *mutex = ((struct cs1550_sem *)ptr) + 2;
  struct cs1550_sem *flag = ((struct cs1550_sem *)ptr) + 3;
于 2017-06-25T18:34:27.527 回答