2015-03-19 3 views
1

Я работаю над кодом. Описание выглядит следующим образом: Существует профессор и количество студентов (предположительно 3 в коде). Студенты могут задавать вопросы и профессор ответит держать следующее mind-Threads and Synchronization

(I) только один человек говорит, в то время,

(б) каждый студент вопрос отвечает профессор, и

(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; 
} 
+0

Это похоже на вариант проблемы обеденных философов, вы можете найти и прочитать об этом? –

+0

Было бы неплохо узнать, что не так с вашим выходом. Или ... какой результат? – Bart

+0

Я проверил его на linux (после исправления void * return для функций потока и void * cast to int с 64 бит) и ** он отлично работает **. Единственное, о чем я могу думать, это то, что программа зависает с тех пор, как профессор контуров «while (1)» и ждет в основном. В чем проблема с вашей продукцией? –

ответ

1

Конечно! (потребовалось время =])

Вы используете эту же id переменную для всех ваших студентов и читали &, пишу ее из разных тем!

удалить глобальную id переменными и вместо

id = (int *)a; 

пишет:

int id = (int)a; 

и сделать ваши функции печати принимают Int аргумент следующим образом:

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

Для того, чтобы сохранить ваш профессор печатает с номером студента, вы можете использовать глобальную переменную, назовем его currentStudent, который будет установлен только после приобретения семафора профессора.
[* Я думаю, что вам нужен еще один семафор для разделения работы профессора от назначения этой переменной]


Если есть еще проблема попробуйте добавить эту строку после каждой печати:

fflush(stdout); 

[ возможно, есть проблема с промывкой печати]

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