Мне была назначена измененная версия проблемы семафора "Санта-Клаус". Санта-Клаус - это нить, которая случайно просыпается, чтобы проверить, сколько и какие нити ожидают, чтобы сообщить ему ( Рабочие эльфы и Сбор эльфов )
То, что я сделал, это рабочий эльф и сбор эльфов потоков:
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;
}
}