线程和同步

时间:2015-03-19 14:04:14

标签: c multithreading synchronization pthreads semaphore

我正在处理代码。描述如下: 有一位教授和一些学生(在代码中假定为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;
}

2 个答案:

答案 0 :(得分:1)

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

您为所有学生使用相同的id变量并阅读&amp;从不同的线程写出来!

删除全局id变量,而不是

id = (int *)a;

写:

int id = (int)a;

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

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

为了让您的教授打印出学生编号,您可以使用全局变量,让我们称之为currentStudent,只有在获得教授的信号量后才会设置。{1}} [*我认为你需要另一个信号量来分配教授的工作来分配变量]


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

fflush(stdout);

[也许还有打印冲洗问题]

答案 1 :(得分:0)

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