Partybreaker

Task

In a certain system, there are two types of threads: N threads of type student and one thread of type partybreaker. Students gather in a party room where an arbitrary number of students can be present. The partybreaker can enter the party room only if there are 3 or more students inside. When the partybreaker is in the room, no other students can (or want to) enter, and the students who are inside may leave. The partybreaker can leave the room only when all students have exited. The number N > 3  is given at the start of the program execution. The task is to properly synchronize the students and the partybreaker.

Anything not explicitly defined in the task can be implemented in any reasonable way.

Thread student(K)
{
   sleep X milliseconds; // X is a random number between 100 and 500
   repeat 3 times {
      enter the party room if the partybreaker is not inside;
      print "Student K has entered the room";
      have fun; // sleep X milliseconds where X is a random number between 1000 and 2000
      exit the party room;
      print "Student K has left the room";
      sleep X milliseconds; // X is a random number between 1000 and 2000
   }
}


Thread partybreaker()
{
   while there are students in the system {
      sleep X milliseconds; // X is a random number between 100 and 1000
      enter the party room if there are 3 or more students inside;
      print "Partybreaker has entered the room";
      exit the room if there are no more students inside;
      print "Partybreaker has left the room";
   }
}
"Sleeping" in milliseconds can be achieved using the function usleep(ms*1000) which delays the program execution for the specified number of microseconds.