Create FooBar class for alternating output #3
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
The C++ code implements a thread synchronization mechanism to ensure the foo and bar methods print "foo" and "bar" alternately,$N$ times. This is the solution for LeetCode Problem 1115: Print FooBar Alternately.Here is the completed PR template:PR Title Format: 1115.Print FooBar Alternately.cpp💡 IntuitionThis is a classic concurrency problem that requires ensuring strict ordering between two separate threads: one running foo() and the other running bar(). The sequence must always be foo, bar, foo, bar, ... for a total of $N$ cycles. The simplest and most direct way to enforce this alternating execution order is by using two mutually exclusive locks (mutexes), one for each function, where the release of one lock signals the next function to proceed.✍️ ApproachThe solution uses two standard C++ mutexes, m1 and m2, to create a lock-step synchronization:Initialization:The constructor initializes n and, crucially, immediately locks m2.m1 is initially unlocked. This ensures that the foo thread, which tries to lock m1, is the first to acquire its lock and run.m2 is initially locked. This ensures that the bar thread, which tries to lock m2, will immediately block and wait until foo releases m2.foo() method:It iterates $N$ times.Acquire m1: m1.lock() ensures only one thread is printing "foo" at a time (though it's only the foo thread using it).Print: printFoo() executes.Release m2: m2.unlock() unblocks the bar thread, allowing it to proceed with its execution cycle.bar() method:It also iterates $N$ times.Acquire m2: m2.lock() forces the thread to wait until foo has released m2.Print: printBar() executes.Release m1: m1.unlock() unblocks the foo thread, allowing it to proceed with the next cycle.This pattern (lock $A$ , run, unlock $B$ $\implies$ lock $B$ , run, unlock $A$ ) guarantees the strict foo, bar alternation.Code Solution (C++)C++#include
#include
using namespace std;
class FooBar {
private:
int n;
// Mutex for the 'foo' thread
mutex m1;
// Mutex for the 'bar' thread
mutex m2;
public:
FooBar(int n) {
this->n = n;
// Initialize m1 as unlocked (default).
// Lock m2 initially, so 'bar' waits for 'foo' to release it.
m2.lock();
}
};
🔗 Related IssuesBy submitting this PR, I confirm that:[x] This is my original work not totally AI generated[x] I have tested the solution thoroughly on leetcode[x] I have maintained proper PR description format[x] This is a meaningful contribution, not spam