I am trying to implement producer-consumer where teacher will teach subjects and students will study them.In my main file,I have started goroutines:
func main(){ w:=WhiteBoard{counter:-1} var x []Student=[]Student{Student{name: "Aditya",w:&w},Student{name: "Abhinav",w:&w},Student{name: "Devansh",w:&w}} var t Teacher =Teacher{w:&w,subjects: []string{"Math","END"}} mu=new(sync.Mutex) wg= new(sync.WaitGroup) for _,student:=range x{ student.attendence() } t.teach() //Teacher starts teaching ->goroutines //Add Student to the waitgroup for _,student:=range x{ go student.w.write(student.name) //student starts writing -> goroutines } wg.Wait()}
Whiteboard is a shared data resource from which teachers will write and students will read:
type WhiteBoard struct { noOfStudents int counter int subject string}func (w *WhiteBoard) write(subject string){ mu.Lock() for w.counter!=-1{ } if subject=="END"{ defer wg.Done() done<-true w.counter++ mu.Unlock() fmt.Println("Teacher is ending the class: ",subject) return } w.subject=subject fmt.Println("Teacher is teaching this subject: ",subject) w.counter++ student_start<-true mu.Unlock() defer wg.Done()}func (w *WhiteBoard) read(name string){ for{ select { case <-done: defer wg.Done() return case <-student_start: fmt.Println(name+" is studying this subject: ",w.subject) w.counter++ if w.counter==w.noOfStudents{ w.counter=-1 } } }}
Now the issue is that when i only run with 1 teacher and 1 student my output looks correct:
-> % go run main.goAditya has given their attendenceTeacher is teaching this subject: MathAditya is studying this subject: MathTeacher is ending the class: END
But with multiple students,the gorutines get stuck and don't exit
-> % go run main.goAditya has given their attendenceAbhinav has given their attendenceDevansh has given their attendenceTeacher is teaching this subject: MathDevansh is studying this subject: Math//Nothing prints after this
I am not sure why this is happening??Here's the full code- https://go.dev/play/p/z3nJZUmEiI8