Learning Journal - Week 31
This past week from CST-334 focused on understanding threads and locks. As someone who was self-taught C++ as a first programming language, threads were something I stumbled across but never got to fully understand. Now learning about how threads work in the context of Operating Systems, it's a lot easier to digest and I feel much more comfortable using and understanding threads.
Recap
Something we learned off the bat was that processes, in the way we've been understanding them up to this point, are essentially threads. A thread is a run of execution, and the operating system splits up time segments for these threads in the scheduling we've been used to seeing. Every process has at least one thread, and more threads can be created manually in a program like C to take better advantage of multi-programming. This means that within a specific program, we can create a separate thread to essentially run "at the same time" as other parts of our program which could help make software more efficient. For example, we can utilize threading to have our program read from a file in the background while it's taking user input at the same time. The biggest difference between threads and separate processes is that threads share memory space with their overall program, while separate processes all have their own memory space.
A problem that this can lead to, however, is the existence of race conditions. A race condition occurs when multiple threads are attempting to read and write to the same data, and depending on which thread occurs first can affect the final output of the operation. The solution for this is mutual exclusion, which is a policy that enforces only one thread acting on data at a given time. It also allows our functions to be atomic, which means that a function can only perform fully and won't have its value affected when the CPU scheduler swaps from one thread to another. This concept feels very familiar to those that have worked with databases and SQL, like in our last class.
Mutual exclusions come in the form of the mutex type in C, part of the POSIX library, which allows us to create a shared lock in the program. This lock can be set or released in code, which can be accessed by any thread. Once we reach a critical section (a portion of code that all threads need to run consisting of a shared variable), then the lock will prevent all but one thread to execute that segment of code. This is important because it ensures that one thread can't read in a variable and lose that value to another thread operating at the same time.
Reflection
It's hard for me to say if there are any portions that I don't fully understand. I find myself to be grasping the overall concepts quite well, but I do believe I struggle most with remembering the code that comes along with it. I have to remind myself about what functions get called and how to interact with the specific code. At first, I also struggled with understanding spinning, spin locks, and ticket locks, but as I spent more time doing the assignments and taking the quiz I forced myself to look again at the lecture material and follow up questions with AI to help further my understanding.
I think most of my struggles come before I get to be more hands on with the information, as I tend to digest information better once I get to put it into practice with programming assignments.
Threads and multi-threadding were a concept I felt I understood relatively well, as it aligns very well with what we've been talking about up to this point. Being able to understand how memory is broken apart, virtualization, and scheduling has helped a lot with fully understanding how threads come into play with the operating system.
Something else that felt easier to grasp the more I thought about it were locks. From our previous class, we learned about SQL and database design which actually had a whole module built about discussing atomicity and locks to prevent separate transactions from accessing the same data. We learned about a process called "serialization" which aimed to ensure that two operations that were acting simultaneously on the same data (like threads acting on a critical section) would result in an output as though they ran sequentially -- one after another. In that class, we also talked about locks and how they were used to prevent multiple transactions from changing or accessing data.
A subject that may come up soon that stems from multi-threading is the subject of multi-cores and multiple threads in a CPU. It feels like a natural progression as we've been focusing on achieving true multi-programming, and being able to break from single-core limitations and explore modern processors sounds like an interesting topic.
Comments
Post a Comment