Thread Synchronization || Using Mutex and Condition Variable
IntuitionThe problem needs the threads to take turns printing, like first 0, then an odd or even number based on sequence. My gut feeling was to use some lockin
# Intuition
The problem needs the threads to take turns printing, like first `0`, then an odd or even number based on sequence. My gut feeling was to use some locking mechanism to control who gets to run when.

# Approach
The tricky part was ensuring that the threads don’t mess up the sequence. I used a `turn` variable to decide whose turn it is:
- If `turn == 1`, it’s the `zero` thread’s turn.
- If `turn == 2`, it’s the `odd` thread’s turn.
- And if `turn == 3`, it’s the `even` thread’s turn.

To manage the threads, I used a `mutex` (for locking) and a `condition_variable` (to signal other threads when to proceed). The threads take turns using `turn` and signal each other when done. The `zero` thread always goes first, prints `0`, then decides whether to give control to odd or even.

This way, everything stays in order and no thread steps out of turn.

# Code
```cpp
class ZeroEvenOdd {
private:
    int n;
    int cur_val;         // Tracks the current number
    mutex mx;            // Mutex for synchronization
    condition_variable cv; // Condition variable for signaling
    int turn;            // Tracks whose turn it is (1: zero, 2: odd, 3: even)

public:
    ZeroEvenOdd(int n) : n(n), cur_val(1), turn(1) {}

    void zero(function<void(int)> printNumber) {
        for (int i = 0; i < n; ++i) {
            unique_lock<mutex> lck(mx);
            cv.wait(lck, [this]() { return turn == 1; });
            printNumber(0);  // Print zero
            turn = (cur_val % 2 == 0) ? 3 : 2; // Switch to even or odd
            cv.notify_all();
        }
    }

    void even(function<void(int)> printNumber) {
        for (int i = 2; i <= n; i += 2) {
            unique_lock<mutex> lck(mx);
            cv.wait(lck, [this]() { return turn == 3; });
            printNumber(cur_val++);  // Print even number
            turn = 1;  // Switch back to zero
            cv.notify_all();
        }
    }

    void odd(function<void(int)> printNumber) {
        for (int i = 1; i <= n; i += 2) {
            unique_lock<mutex> lck(mx);
            cv.wait(lck, [this]() { return turn == 2; });
            printNumber(cur_val++);  // Print odd number
            turn = 1;  // Switch back to zero
            cv.notify_all();
        }
    }
};

['C++']