c - 每个线程都有唯一的信号量

标签 c multithreading semaphore

我被分配了“圣诞老人”信号量问题的修改版本。 圣诞老人是一个线程,它会随机醒来,检查有多少个以及什么类型的线程正在等待向他报告(工作 Sprite 收集 Sprite )

我制作的是工作 Sprite 收集 Sprite 线程:

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);
    }
}

因此,这里 Sprite 计数受到保护,因为线程只能在 elveCountMutex 锁定时访问计数器。我可以理解这一点,而且这似乎是合乎逻辑的。之后线程应该阻塞并等待圣诞老人解除阻塞。 因此,根据我的阅读,一旦信号量达到值 0,线程就会阻塞。任何大于 0 的值都不会阻塞它,负值表示有多少线程正在等待信号量解锁。

因此,一旦线程运行完成,它们就会减少信号量并阻塞。

但是,我似乎无法理解作业的这一部分:

要开始收集 session ,至少需要一名工作 Sprite 和三名收集 Sprite 。 • 如果有足够多的 Sprite 出席,两个 session 都可以开始,收集 session 始终具有优先权,并且所有不再需要的工作 Sprite 都会恢复工作

假设我有 3 个工作 Sprite ,而我只需要 1 个,如何释放剩余的 2 个线程?我需要为每个线程使用单独的信号量吗?或者我错过了什么?

编辑:我的错,我完全忘记告诉圣诞老人实现。 圣诞老人醒来并释放信号量,这样:

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;
      }
   }

最佳答案

我不明白你对信号量的管理

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);
    }
}

获取但从未释放elveCountMutexworkElfSem,并且处于无限循环中。 collectingElf 也(尝试)获取 elveCountMutex 但在 workingElf 中转一圈后我将无法做到这一点

如果你的信号量不是递归的,workingElf也会在一轮后被阻塞,因为无法再次获取信号量。如果信号量是递归的,则不能达到无限深度,并且 workingElf 将在足够的循环后阻止自身

关于c - 每个线程都有唯一的信号量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/55502461/

相关文章:

使用信号量和监视器的 Java Unisex 浴室

c - 当进程进入信号量(临界区)并休眠时会发生什么?

c - C 中插入时指针未修改

c - 在 C 中定义长度前缀 const 宽字符串

C语言 : lookup in char array

c - 使用 MPI 收集来自不同流程的小矩阵部分

C# 线程访问 if block ,其条件返回 false

c++ - 来自主线程的 VTK 窗口线程,C++

c - 如何避免mutex_lock阻塞?

c - 如果有人正在等待共享信号量,如何检查 C Posix 线程?