首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >每个线程的唯一信号量

每个线程的唯一信号量
EN

Stack Overflow用户
提问于 2019-04-03 18:58:32
回答 1查看 193关注 0票数 0

我被分配了一个修改版本的“圣诞老人”信号量问题。Santa Claus是一条随机唤醒的线程,以检查有多少线程等待向他报告(Work精灵收集精灵)

我制作的是work elf收集精灵线程:

代码语言:javascript
复制
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被锁定时访问计数器。这我能理解,这似乎是合乎逻辑的。之后,线程应该阻止并等待Santa解除阻塞。因此,根据我所读到的,一旦信号量达到0,线程就会阻塞。任何高于0的东西都不会阻止它,负值表示有多少线程在等待信号量被解锁。

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

然而,我似乎无法理解的是,这一部分的任务:

为了开始一个收集会议,至少需要一个工作精灵和三个收集精灵。·如果有足够多的精灵出现,两个会议都可以开始,收集会议总是有优先权的,并且所有的工作精灵不再需要继续他们的工作,

如果我有三个工作精灵,而我只需要一个,我如何释放剩下的2个线程?每个线程需要一个单独的信号量吗?还是我漏掉了什么?

编辑:我的错,我完全忘了告诉有关圣诞老人的实现。Santa以这种方式唤醒并释放信号量:

代码语言:javascript
复制
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;
      }
   }
EN

回答 1

Stack Overflow用户

发布于 2019-04-03 19:10:05

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

在……里面

代码语言:javascript
复制
void *collectingElf(void *arg, int semaphoreIndex) {
    while (1) {
        ...
        sem_wait(&collectingElveSem);
    }
}

它得到但永远不会释放collectingElveSem,并且在一个无限循环中?

在……里面

代码语言:javascript
复制
void *workingElf(void *arg)                             //same as collecting elf
{
    while (1) {
        sem_wait(&elveCountMutex);
        ...
        sem_wait(&workElfSem);
    }
}

它得到但永远不会释放elveCountMutexworkElfSem,以及无限循环中的。collectingElf也(尝试)获得elveCountMutex,但是在workingElf转一圈之后,我就不能做了

如果您的信号量不是递归的,workingElf也会在一轮之后被阻塞,因为无法再次获得信号量。如果信号量是递归的,这不可能是无限深的,workingElf会在循环足够多之后阻止自己。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/55502461

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档