Уникальный семафор для каждого потока - PullRequest
0 голосов
/ 03 апреля 2019

Мне была назначена измененная версия проблемы семафора "Санта-Клаус". Санта-Клаус - это нить, которая случайно просыпается, чтобы проверить, сколько и какие нити ожидают, чтобы сообщить ему ( Рабочие эльфы и Сбор эльфов )

То, что я сделал, это рабочий эльф и сбор эльфов потоков:

void *collectingElf(void *arg, int semaphoreIndex) {
    while (1) {
        sem_wait(&elveCountMutex);                          //semaphore for critical section, the number of elves
        printf("\nCollecting! %d\n", (int) pthread_self()); // thread is collecting stuff
        sleep((unsigned int) (rand() % 4));                           // thread sleeps for a random amount of time

        printf("Done collecting! %d\n", (int) pthread_self());    // Print process ID, just for easier tracking
        sem_post(&elveCountMutex);                            // Release the elve count semaphore
        sem_wait(&collectingElveSem);

    }
}

void *workingElf(void *arg)                             //same as collecting elf
{
    while (1) {
        sem_wait(&elveCountMutex);
        printf("\nWorking! %d\n", pthread_self());
        sleep(1);
        workingElveCount++;
        printf("Done working! %d\n", pthread_self());
        sem_wait(&workElfSem);
        sem_post(&elveCountMutex);
    }
}

Так что здесь счет эльфов защищен, так как потоки могутДоступ к счетчикам возможен только тогда, когда elveCountMutex заблокирован.Это я могу понять, и это кажется логичным.После этого поток должен заблокироваться и ждать, пока Санта разблокирует его.Итак, из того, что я прочитал, когда семафор достигнет значения 0, поток заблокируется.Все, что больше 0, не будет блокировать его, а отрицательное значение указывает, сколько потоков ожидает разблокировки семафора.

Таким образом, по завершении работы потоков они уменьшают семафор и блокируют.

Однако то, что я не могу понять, - это часть задания:

Для начала собирательного собрания, по крайней мере, один рабочий эльф и три собирающих эльфа *Необходимо 1029 *• Если присутствует достаточное количество эльфов, чтобы оба собрания могли начаться, собирательное собрание всегда имеет приоритет, и все рабочие эльфы больше не нужны, возобновляют свою работу .

Скажите, если у меня есть 3 работыэльфы, а мне нужно только 1, как мне выпустить оставшиеся 2 темы?Нужен ли отдельный семафор для каждого потока?Или я что-то упустил?

Редактировать: Плохо, я совсем забыл рассказать о реализации Santa . Санта просыпается и освобождает семафоры следующим образом:

void* Santa(void *arg)
{
   while (1) {
      sleep((unsigned)rand() % 4);                                  //Santa sleeps randomly between 0 and 3 seconds;
      sem_wait(&elveCountMutex);                                      //access both elf counters
      if(workingElveCount>=2 && collectingElveCount >= 3)            //decide which meeting should commence
      {
         int releaseWorkElveCount = workingElveCount-1;
         for(int i = 0;i<releaseWorkElveCount;i++)
         {
            sem_post(&workElfSem);
         }
         sleep(5);
         collectingMeeting(&collectingMeetingThread);                //This just prints that we are in a collecting meeting 
         pthread_join(collectingMeetingThread,0);
         sem_wait(&elveCountMutex);
         for(int i=0;i<workingElveCount;i++)
         {
             sem_post(&workElfSem);
         }
         for(int i=0;i<collectingElveCount;i++)
         {
             sem_post(&collectingElveSem);
         }
         workingElveCount=0;
         collectingElveCount=0;
      }
   }

1 Ответ

0 голосов
/ 03 апреля 2019

Я не понимаю вашего управления семафором

В

void *collectingElf(void *arg, int semaphoreIndex) {
    while (1) {
        ...
        sem_wait(&collectingElveSem);
    }
}

, который получает, но никогда не выпускает collectingElveSem, и что в бесконечном цикле?

В

void *workingElf(void *arg)                             //same as collecting elf
{
    while (1) {
        sem_wait(&elveCountMutex);
        ...
        sem_wait(&workElfSem);
    }
}

, которые получают, но никогда не освобождают elveCountMutex и workElfSem, и это в бесконечном цикле.collectingElf также (попытайтесь) получить elveCountMutex, но я не смогу сделать это после одного хода в workingElf

Если ваш семафор не рекурсивный, workingElf также будет заблокирован после одного хода, потому что несмог снова получить семафоры.Если семафор рекурсивный, это не может быть бесконечно глубоко, и workingElf будет блокироваться после достаточного количества циклов

...