fork download
  1. #include <iostream>
  2. #include <thread>
  3. #include <vector>
  4. #include <atomic>
  5. #include <chrono>
  6. #include <algorithm>
  7.  
  8. using namespace std;
  9.  
  10. const int NUM_THREADS = 5;
  11. atomic<bool> choosing[NUM_THREADS];
  12. atomic<int> number[NUM_THREADS];
  13.  
  14. // Utility: Get max ticket number
  15. int get_max_ticket() {
  16. int max_val = 0;
  17. for (int i = 0; i < NUM_THREADS; ++i) {
  18. max_val = max(max_val, number[i].load());
  19. }
  20. return max_val;
  21. }
  22.  
  23. // Bakery Lock
  24. void lock(int id) {
  25. choosing[id] = true;
  26. cout << "Thread " << id << " is choosing a ticket...\n";
  27. number[id] = get_max_ticket() + 1;
  28. choosing[id] = false;
  29.  
  30. cout << "Thread " << id << " got ticket #" << number[id] << " and is waiting to enter...\n";
  31.  
  32. for (int j = 0; j < NUM_THREADS; ++j) {
  33. while (choosing[j]) {} // wait while other thread is choosing
  34. while (number[j] != 0 &&
  35. (number[j] < number[id] ||
  36. (number[j] == number[id] && j < id))) {
  37. // Waiting for its turn
  38. }
  39. }
  40. }
  41.  
  42. // Bakery Unlock
  43. void unlock(int id) {
  44. number[id] = 0;
  45. }
  46.  
  47. // Critical Section simulation
  48. void critical_section(int id) {
  49. lock(id);
  50.  
  51. cout << "Thread " << id << " is ENTERING critical section.\n";
  52. this_thread::sleep_for(chrono::milliseconds(rand() % 1500 + 500));
  53. cout << "Thread " << id << " is EXITING critical section.\n\n";
  54.  
  55. unlock(id);
  56. }
  57.  
  58. int main() {
  59. // Initialize
  60. for (int i = 0; i < NUM_THREADS; ++i) {
  61. choosing[i] = false;
  62. number[i] = 0;
  63. }
  64.  
  65. // Launch threads
  66. vector<thread> threads;
  67. for (int i = 0; i < NUM_THREADS; ++i) {
  68. threads.emplace_back(critical_section, i);
  69. this_thread::sleep_for(chrono::milliseconds(300)); // simulate random arrival like customers
  70. }
  71.  
  72. for (auto &t : threads) {
  73. t.join();
  74. }
  75.  
  76. return 0;
  77. }
  78.  
Success #stdin #stdout 4.65s 5288KB
stdin
Standard input is empty
stdout
Thread 0 is choosing a ticket...
Thread 0 got ticket #1 and is waiting to enter...
Thread 0 is ENTERING critical section.
Thread 1 is choosing a ticket...
Thread 1 got ticket #2 and is waiting to enter...
Thread 2 is choosing a ticket...
Thread 2 got ticket #3 and is waiting to enter...
Thread 3 is choosing a ticket...
Thread 3 got ticket #4 and is waiting to enter...
Thread 4 is choosing a ticket...
Thread 4 got ticket #5 and is waiting to enter...
Thread 0 is EXITING critical section.

Thread 1 is ENTERING critical section.
Thread 1 is EXITING critical section.

Thread 2 is ENTERING critical section.
Thread 2 is EXITING critical section.

Thread 3 is ENTERING critical section.
Thread 3 is EXITING critical section.

Thread 4 is ENTERING critical section.
Thread 4 is EXITING critical section.