【问题标题】:Threads and Synchronisation线程和同步
【发布时间】:2015-05-22 16:36:13
【问题描述】:

我正在编写代码。说明如下: 有教授和学生人数(代码中假设为 3)。学生可以提出问题,教授将在牢记以下内容的情况下进行答复-

(i) 一次只有一个人在讲话,

(ii) 每个学生的问题都由教授回答,并且

(iii) 在教授回答完前一个问题之前,没有学生提出另一个问题。

代码的可能输出是:

Student 0 enters the office.
Student 1 enters the office.
Student 1 asks a question.
Professor starts to answer question for student 1.
Professor is done with answer for student 1.
Student 1 is satisfied.
Student 0 asks a question.
Professor starts to answer question for student 0.
Professor is done with answer for student 0.
Student 0 is satisfied.
Student 0 leaves the office.
Student 2 enters the office.
Student 2 asks a question.
Professor starts to answer question for student 2.
Professor is done with answer for student 2.
Student 2 is satisfied.
Student 2 leaves the office.

我的代码附在下面,我没有得到想要的输出。非常感谢对我做错的任何帮助。

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <semaphore.h>
#include <sys/fcntl.h>

sem_t student,professor, askQuestion,numberOfStudents;
int id=0,number=0;

void AnswerStart()
{
  printf("Professor starts to answer question for studnet %d\n",id);
  return;
}

void AnswerDone()
{
  printf("Professor is done with the answer of student %d\n",id);
  return;
}

void QuestionStart()
{
    printf("Student %d asked a question\n",id);
    return;
}

 void QuestionDone()
{
  printf("Studnet %d is stisfied\n",id);
  return;
}

void Studnet(void *a)
{
  sem_wait(&numberOfStudents);
  number++;
  printf("Student %d enters office\n",(int *)a);
  sem_post(&numberOfStudents);

  sem_wait(&askQuestion);
  id = (int *)a;
  QuestionStart();
  sem_post(&professor);
  sem_wait(&student);
  QuestionDone();
  sem_post(&askQuestion);

  sem_wait(&numberOfStudents);
  number--;
  printf("Student %d leaves office\n",(int *)a);
  sem_post(&numberOfStudents);
}

void Professor(void *a)
{
  printf("Professor is in office\n");
  while(1){
     sem_wait(&professor);
     AnswerStart();
     AnswerDone();
     sem_post(&student);
     sem_wait(&numberOfStudents);
     if(number==0)
     return;
     sem_post(&numberOfStudents);
 }

}


int main(){

sem_init(&student,0,0);
sem_init(&professor,0,0);
sem_init(&askQuestion,0,1);
sem_init(&numberOfStudents,0,1);

pthread_t studentThread[3], professorThread;
pthread_create(&professorThread,NULL,Professor,NULL);
pthread_create(&studentThread[0],NULL,Studnet,(void *)0);
pthread_create(&studentThread[1],NULL,Studnet,(void *)1);
pthread_create(&studentThread[2],NULL,Studnet,(void *)2);

pthread_join(studentThread[0],NULL);
pthread_join(studentThread[1],NULL);
pthread_join(studentThread[2],NULL);
pthread_join(professorThread,NULL);

sem_destroy(&student);
sem_destroy(&professor);
sem_destroy(&askQuestion);
sem_destroy(&numberOfStudents);
return 0;
}

【问题讨论】:

  • 这似乎是哲学家就餐问题的变体,您可能想搜索并阅读它?
  • 很高兴知道您的输出有什么问题。或者...输出是什么?
  • 我在 linux 上检查了它(在修复了线程函数的 void* return 和 void* 自 64 位以来强制转换为 int 之后)并且 它工作正常。我能想到的唯一一件事是程序挂起,因为教授循环 while(1) 并且正在等待主要。你的输出有什么问题?
  • @ArnonZilca 我得到这个输出:Professor is in office Student 0 enters office Student 1 enters office Student 2 enters office Professor starts to answer question for studnet 0 Student 0 asked a question Student 1 asked a question Student 2 asked a question Professor is done with the answer of student 2 Studnet 2 is stisfied Studnet 2 is stisfied Studnet 2 is stisfied Professor starts to answer question for studnet 2 Student 0 leaves office Student 1 leaves office Student 2 leaves office Professor is done with the answer of student 2
  • 教授开始回答在学生提出问题之前显示。

标签: c multithreading synchronization pthreads semaphore


【解决方案1】:

当然!(花了一段时间=])

您为所有学生使用相同的 id 变量,并从不同的线程读取和写入它!

删除全局id变量,而不是

id = (int *)a;

写:

int id = (int)a;

并使您的打印函数采用 int 参数,如下所示:

void QuestionStart(int id)
void QuestionDone(int id)

为了让你的教授打印学生号,你可以使用一个全局变量,我们称之为currentStudent,它只会在获取教授的信号量后设置。
[* 我认为您需要另一个信号量来将教授的工作与分配该变量分开]


如果仍有问题,请尝试在每次打印后添加此行:

fflush(stdout);

[可能还有打印冲洗问题]

【讨论】:

    【解决方案2】:
    given the criteria stated in the question...
    
    a common resource is the professor    
    a common resource is the office
    
    
    the professor resource can have several states:
    
    not in office
    entering office
    in office, doing nothing
    in office listening to question
    in office answering question
    (optional exiting office)
    
    
    each student resource can have several states:
    
    waiting for professor to be in office, doing nothing
    (transition student entering office)
    student in office stating question
    student in office listening to answer
    (transition student exiting office)
    
    
    there are criteria:
    
    a student cannot enter office unless
    --professor is in office, doing nothing
    
    professor cannot exit office unless
    --professor is in office doing nothing
    
    
    
    
    the office resource can have several states:
    
    no one in office
    professor entering office
    professor in office doing nothing
    professor in office and student entering
    professor in office and student in office
    professor in office and student exiting office
    professor exiting office
    
    
    using the above (or develope your own)
    write out a state diagram
    determine when state changes are allowed for each resource
    (office, student(s), professor)
    
    It seems, to me, that the main restriction
    is the state of the office
    so perhaps make the state of the office
    a common datum, protected with a mutex
    
    use enum variables for the state of each resource
    
    there is only one professor, 
    -- suggest professor be handled by main()
    
    there are several students,
    -- suggest thread for each student
    
    after writing the state diagrams 
    with the transition criteria 
    for each state change to the next state
    The actual coding should be very simple
    
    I would suggest using a mutex rather than a semaphore,
    just to keep it simple
    especially as there can be only one student 
    using the resource at any one time, so no need for any counting semaphore
    
    suggest, for any one resource, 
    the states be tested using a switch statement
    with each case being one state, 
    and each case has the criteria for when to switch to the next state
    

    【讨论】:

      猜你喜欢
      • 2011-06-10
      • 2011-06-15
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-09-11
      相关资源
      最近更新 更多