这个问题要求使用两个信号量,一个作为互斥量,一个作为计数信号量,并且该对用于模拟学生和教师助手之间的交互 .
我已经能够轻松地利用二进制信号量了,但是我似乎找不到很多显示计数信号量使用的例子,所以我很确定我错了,这导致我的代码无法正常执行 .
我的代码如下
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <stdlib.h>
#include <semaphore.h>
#include <time.h>
#include <sys/types.h>
void *taThread();
void *student();
sem_t taMutex;
sem_t semaphore;
int main()
{
pthread_t tid1;
srand(time(NULL));
sem_init(&taMutex,0,1);
sem_init(&semaphore,1,3);
pthread_create(&tid1, NULL, &taThread, NULL);
pthread_join(tid1, NULL);
return 0;
}
void *taThread()
{
pthread_t tid2[10];
int it = 0;
printf("Teacher's Assistant taking a nap.\n");
for (it = 0; it < 10; it ++)
{
pthread_create(&tid2[it], NULL, &student, NULL);
}
for (it = 0; it < 10; it ++)
{
pthread_join(tid2[it], NULL);
}
}
void *student()
{
int xTime;
xTime = rand() % 10 + 1;
if (sem_wait(&taMutex) == 0)
{
printf("Student has awakened TA and is getting help. This will take %d minutes.\n", xTime);
sleep(xTime);
sem_post(&taMutex);
}
else if (sem_wait(&semaphore) > 2 )
{
printf("Student will return at another time.\n");
}
else
{
sem_wait(&semaphore);
printf("Student is working on their assignment until TA becomes available.\n");
sem_wait(&taMutex);
sem_post(&semaphore);
printf("Student is entering the TA's office. This will take %d minutes", xTime);
sleep(xTime);
sem_post(&taMutex);
}
}
我的主要问题是:如何让线程同时轮询计数信号量?
我正在尝试获得备份,一些学生被迫离开(或退出线程),而其他人则在信号量等待 . 任何帮助表示赞赏,并将提供任何澄清 .
1 回答
我不确定你的 class /老师是否想要在这里做出特殊的区分,但从根本上说,计数信号量只是一个初始化为1的二进制信号量,所以当你把它倒数(“P”)为零时它就是“忙” (像互斥锁一样锁定)当你释放它(“V”)时,它会计入最大值1并且现在“非忙”(解锁) . 计数信号量以较高的初始值开始,通常用于计算某些资源(例如房间中的3个可用椅子),因此当您将其计数时,可能仍有一些剩余 . 当您完成使用计算的资源时(例如,当“学生”离开“TA的办公室”时),您将其重新计算(“V”) .
使用POSIX信号量,通话:
说这是一个进程共享的信号量(第二个参数非零),而不是一个线程共享的信号量;你不确定某些系统是否会给你一个错误 - 一个失败的
sem_init
调用,即如果&semaphore
不在进程共享区域 . 你应该可以只使用0, 3
. 否则,这很好:它实际上是说"office"中有三个"unoccupied chairs" .除此之外,您需要使用
sem_trywait
(如@pilcrow建议),sem_timedwait
或中断sem_wait
调用的信号(例如,SIGALRM
),以便让某些学生试图在"office"中获得"seat"发现他在一段时间内无法获得一个 . 只需调用sem_wait
即表示"wait until there's an unoccupied chair, even if that takes arbitrarily long" . 只有两件事可以阻止这种潜在的无限等待:要么椅子可用,要么信号中断呼叫 .(来自各种
sem_*
函数的返回值告诉您是否"got"等待的是"chair" .sem_wait
等待"forever",sem_trywait
等待完全没有,sem_timedwait
等待直到你"get the chair"或时钟用尽,以先发生者为准 . )