已为我分配了“圣诞老人”信号灯问题的修改版本。 圣诞老人是一个线程,它会随机唤醒,以检查有多少线程正在等待向他报告(工作精灵和收集精灵 >)
我所做的是工作精灵和收集精灵线程:
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的值将不会阻止它,并且负值表示有多少线程正在等待信号量被解锁。
因此,一旦线程运行完毕,它们就会减少信号量并阻塞。
但是,我似乎无法理解的是这部分作业:
要开始召开收集会议,至少需要一个工作精灵和三个收集精灵。 •如果有足够的精灵出席这两次会议,则开会会议 始终具有优先权,不再需要的所有工作精灵都恢复工作。
假设我有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;
}
}
答案 0 :(得分: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
和workElfSem
,并且陷入无限循环。 collectingElf
也(尝试)获得elveCountMutex
,但是一转workingElf
后我将无法做
如果您的信号量不是递归的,workingElf
也将在转一圈后被阻止,因为无法再次获得该信号量。如果信号量是递归的,则不可能是无限深的,workingElf
将在足够的循环后自行阻塞