rand() в C с модулем никогда не запускается

Я пытаюсь реализовать симуляцию реального мира, включающую синхронизацию, и когда у меня есть событие с вероятностью 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;
}

1 ответ

Я всегда использовал эту формулу для получения смещения rand(). Я считаю, что это получает более равномерное распределение, чем метод по модулю.

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

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

Что вы подразумеваете под

Я изменил sys.c для создания системных вызовов up и down, которые действуют как семафоры.

Я не думаю, что это очень хорошая идея. Вы уверены, что нет более простого и безопасного способа сделать атомарные приращения, чем изменение библиотеки времени выполнения? Оттуда может исходить ваша ошибка, так как логика кода, который вы разместили, выглядит корректно и, вероятно, будет работать нормально, если вы не испортили время выполнения только для чтения, если только нет ошибки в нем библиотека.

Когда вы выделяете память для своих "семафоров":

 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;
Другие вопросы по тегам