c - 每个线程的唯一信号量
问题描述
我被分配了“圣诞老人”信号量问题的修改版本。 圣诞老人是一个线程,它随机醒来检查有多少和什么样的线程在等待向他报告(工作精灵和收集精灵)
我所做的是工作精灵和收集精灵线程:
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 的都不会阻塞它,负值表示有多少线程在等待信号量被解锁。
因此,一旦线程运行完成,它们就会递减信号量并阻塞。
但是,我似乎无法掌握的是作业的这一部分:
要开始收集会议,至少需要一个工作精灵和三个收集精灵。• 如果有足够多的精灵在场,两个会议都可以开始,则收集会议始终具有优先权,所有不再需要的工作精灵恢复工作。
假设我有 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;
}
}
解决方案
我不明白你对信号量的管理
在
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
and workElfSem
,并且在无限循环中。collectingElf
也(试图)得到elveCountMutex
,但我一转身就做不到workingElf
如果你的信号量不是递归的workingElf
,一转后也会被阻塞,因为无法再次获得信号量。如果信号量是递归的,这不可能是无限深的,并且workingElf
会在足够多的循环后自行阻塞
推荐阅读
- php - PHP MYSQL 中的错误跟踪 - 是否有更多信息?
- mysql - 如何根据条件过滤关联的子类
- mysql - 如何在 docker 中使用正确版本的 MySQL?
- ruby-on-rails - 纱线运行构建 - 没有这样的文件或目录:'运行'
- amazon-web-services - AWS Lambda 跟踪和限制来自用户的经过身份验证的调用
- c# - LINQ:尝试提取数据并连接关系不同的 3 个表(一对一、一对多)
- flutter - 当您不知道文档名称时访问文档
- reactjs - 在滚动视图中渲染反应导航屏幕
- docker - 尝试使用 docker:dind 时 gitlab-ci 失败
- r - Dbplyr:in_schema 为两个不同的数据库使用相同的连接