cd week_six
Journal Entry Week 6
Topics We Covered
The main topics we covered were:
- Anderson-Dolan method
- Using locks and condition variables to make a normal class thread-safe
- State variables in concurrent code
- Why busy waiting is bad
-
Why
wait()is different from a normal loop - Synchronization barriers with semaphores
- Reusable barriers
- Turnstile pattern with semaphores
- How semaphores compare to locks and condition variables
Explaining the Topics
The Anderson-Dolan method felt like a step-by-step recipe for taking a normal class and turning it into a thread-safe one. Instead of just randomly throwing locks into code and hoping it works, it gives a process: start with a normal design, add a lock, protect the methods, add condition variables, add signal or broadcast, and then add waits inside loops. I liked that because concurrency usually feels messy, and this made it feel more structured.
State variables were also a big deal this week. What clicked for me is that they help describe what the program is currently doing, like whether something is empty, full, being read, or being written. That makes it easier to know what condition should make a thread stop or continue.
The part about busy waiting made a lot of sense too. A thread can sit there over and over checking whether something changed, but that wastes CPU and can actually hold a lock so nothing else can move forward. The important part with condition variables is that wait() does more than just pause. It releases the lock, lets another thread do useful work, and then re-acquires the lock when it wakes up.
We also got into synchronization barriers with semaphores. That was about making a bunch of threads all stop at the same point until every thread gets there. Once the last thread arrives, they start getting released one at a time, kind of like a turnstile. Then for a reusable barrier, you also have to reset things so the barrier can be used again later.
Least-Understood Topics
The hardest topic for me this week was probably the reusable semaphore barrier. I get the big-picture idea of it: all threads need to arrive before any can continue, and then at the end it needs to reset itself. But keeping track of the semaphore values and the exact order of the waits and signals is where my brain starts getting scrambled a little.
What Confused Me
The part that makes sense is the purpose of the barrier. I understand why you’d want all threads to meet at one point before moving on. That part feels pretty intuitive. What gets confusing is the bookkeeping side of it, especially how the barrier semaphore changes over time and why one extra wait is needed at the end to reset it correctly. I also have to think pretty hard about why accessing count outside protection would break thread safety, even when the logic seems simple at first.
Another thing that took me a minute was the idea that a normal while loop holding a mutex can accidentally block the very thread that needs to make progress. Once that got explained with wait() releasing the lock, it made sense, but before that I could definitely see myself making that mistake in my own code.
Aha Moments
My biggest aha moment was probably understanding why condition-variable waits have to go inside while loops and why wait() is so powerful. Before, it kind of just looked like a special function call. Now I see that it is solving two problems at once: it avoids busy waiting and it prevents a thread from hogging the lock while waiting for something to change. That made the whole condition variable idea click way more clearly for me.
I also liked the Anderson-Dolan method because it made concurrency feel less random. It gave me a pattern I can actually follow instead of just guessing.
Questions I Still Have
I’m wondering if next we’ll get more into comparing when semaphores are the better tool versus when locks and condition variables are better. It seems like semaphores are really powerful, but also easier to mess up because you have to keep track of what the value means. I also still want more practice tracing semaphore values step by step, because that seems like the main thing that makes those problems hard for me.
Connections to Other Classes and Applications
I could definitely connect this week’s material to programming projects in general, especially anything involving multiple workers, tasks, or queues. The barrier example also made me think about real systems where a bunch of things have to finish before the next phase can start. It also connects back to earlier concurrency topics because now it feels like we’re moving beyond just “avoid race conditions” and into “design the whole system so threads cooperate correctly and efficiently.”
Overall, this week made concurrency feel a little less mysterious, but also showed me how careful you really have to be. I feel better about the big ideas, but the exact semaphore logic still feels like something I’d need to trace slowly more times before I’d feel fully confident with it.
Comments
Post a Comment