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

问题描述 投票:1回答: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);
  }
}

我的主要问题是:如何让线程同时轮询计数信号量?我正在尝试进行备份,有些学生被迫无助地离开(或退出线程),而另一些学生则等待信号量。感谢您的协助,并将提供任何说明。

c multithreading posix semaphore
1个回答
1
投票

[我不确定您的班级/老师是否要在此处进行特殊区分,但是从根本上讲,计数信号量基本上等于初始化为1的二进制信号量,1因此,当您对其进行计数时( P“)变为零,则它变为“忙”(像互斥锁一样被锁定),当您释放它(“ V”)时,它的计数达到最大值1,现在变为“不忙”(已解锁)。计数信号量通常以较高的初始值开始,通常用于计数某些资源(例如,房间中有3个可用的椅子),因此当您对其进行计数时,可能还会剩下一些。使用完所计算的资源后(例如,当“学生”离开“助教的办公室”时),您将其备份(“ V”)。

使用POSIX信号灯,该电话:

sem_init(&semaphore,1,3);

表示这是一个进程共享的信号量(第二个参数非零),而不是线程共享的信号量;您似乎不需要它,而且我不确定某些系统是否会给您带来错误-失败的sem_init调用,即-如果&semaphore不在进程共享区域中。您应该只能使用0, 3。否则,这很好:实际上是在“办公室”中有三把“空椅子”。

[除此之外,您需要使用sem_trywait(如@pilcrow建议),sem_timedwait或信号来中断sem_wait调用(例如SIGALRM),以便获得一些试图在“办公室”中获得一个“座位”的学生,发现他在一段时间内无法获得一个。仅仅调用sem_wait就意味着“等待直到有空椅子,即使这需要花费很长时间”。只有两件事阻止了这种可能无限的等待:要么有椅子可供使用,要么有信号打断了通话。

(各种sem_*函数的返回值告诉您是否“丢失”了正在等待的“椅子”。sem_wait永远等待“,sem_trywait根本不等待,而[C0 ]一直等到您“拿起椅子”或时钟用完,以先到者为准。)


1真正的二进制信号量与计数信号量之间的真正区别在于,二进制信号量不提供计数功能。它要么被收购(并且收购将阻止),要么未被收购(并且收购将成功并阻止其他收购)。各种实现可以考虑以无操作或错误的方式释放已经释放的二进制信号量(例如,运行时紧急)。 POSIX根本不提供二进制信号量:sem_timedwait初始化计数信号量,您有责任将其设置为1,并且在已经释放时不通过释放来过度增加它。另请参见下面的注释。

© www.soinside.com 2019 - 2024. All rights reserved.