首页 文章

使用posix C同时轮询信号量多次

提问于
浏览
1

这个问题要求使用两个信号量,一个作为互斥量,一个作为计数信号量,并且该对用于模拟学生和教师助手之间的交互 .
我已经能够轻松地利用二进制信号量了,但是我似乎找不到很多显示计数信号量使用的例子,所以我很确定我错了,这导致我的代码无法正常执行 .
我的代码如下

#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 回答

  • 1

    我不确定你的 class /老师是否想要在这里做出特殊的区分,但从根本上说,计数信号量只是一个初始化为1的二进制信号量,所以当你把它倒数(“P”)为零时它就是“忙” (像互斥锁一样锁定)当你释放它(“V”)时,它会计入最大值1并且现在“非忙”(解锁) . 计数信号量以较高的初始值开始,通常用于计算某些资源(例如房间中的3个可用椅子),因此当您将其计数时,可能仍有一些剩余 . 当您完成使用计算的资源时(例如,当“学生”离开“TA的办公室”时),您将其重新计算(“V”) .

    使用POSIX信号量,通话:

    sem_init(&semaphore,1,3);
    

    说这是一个进程共享的信号量(第二个参数非零),而不是一个线程共享的信号量;你不确定某些系统是否会给你一个错误 - 一个失败的 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"或时钟用尽,以先发生者为准 . )

相关问题