No history yet

Introduction to Concurrency

What Is Concurrency?

Think about a busy coffee shop. If there's only one barista, they have to take an order, make the coffee, froth the milk, and hand it to the customer before starting the next order. It's a slow, step-by-step process.

Now, imagine two baristas working at the same time. One can take orders while the other makes drinks. They can work on different parts of different orders simultaneously. This is the essence of concurrency: multiple tasks making progress at the same time, without necessarily finishing one before starting another.

Concurrency

noun

The ability of different parts or units of a program, algorithm, or problem to be executed out-of-order or in partial order, without affecting the final outcome.

In computing, these tasks are processes or threads. Your computer is doing this right now. It's running your web browser, your operating system's background services, and maybe a music player, all seemingly at once. This ability is crucial for two main reasons: performance and responsiveness.

Most modern processors have multiple cores, which are like individual brains inside the main chip. Concurrency allows software to use all of these cores, getting more work done in less time. It also keeps applications responsive. When you click a button in an app to download a large file, you don't want the entire app to freeze until the download is done. Concurrency allows the download to happen in the background while you continue to use the app.

The Challenge of Sharing

Concurrency isn't as simple as just letting multiple tasks run wild. Problems arise when these tasks need to access the same piece of information, or a shared resource, like a variable in memory or a file on a disk.

Let's go back to the coffee shop. What if both baristas need to use the single espresso machine at the exact same moment? Or what if they both try to update the number of coffee beans left in the bag? Barista A sees 100 beans and decides to use 20. At the same time, Barista B sees 100 beans and decides to use 30. Barista A updates the count to 80. A moment later, Barista B updates it to 70. Now the count is wrong. There should be 50 beans left, but the system says 70. This kind of conflict is called a race condition.

Race Condition

noun

A flaw in a system or process where the output is dependent on the sequence or timing of other uncontrollable events. It becomes a bug when events do not happen in the order the programmer intended.

In the example above, both processes read the initial balance before either one could save its result. Process A’s work was completely overwritten by Process B. The final result depends entirely on which process finishes last. This leads to unpredictable behavior and corrupted data.

Keeping Things in Order

To prevent these problems, we need rules for accessing shared resources. This is where the concepts of mutual exclusion and synchronization come in. They are the tools programmers use to safely manage concurrency.

Mutual Exclusion

noun

A property of concurrency control which ensures that no two concurrent processes are in their critical section at the same time. It's a requirement for preventing race conditions.

Mutual exclusion is like putting a lock on the espresso machine. Only one barista can have the key at a time. While one has the key, they can use the machine without interruption. When they're done, they put the key back, and another barista can take it. The part of the code that accesses the shared resource (the bank balance, the espresso machine) is called a critical section.

Synchronization is the broader concept of coordinating the execution of multiple tasks. It's not just about locking others out; it's also about ensuring tasks happen in the correct order or signal to each other when work is done. It's the full set of rules that lets our baristas work together efficiently without spilling coffee on each other.

Concurrency allows tasks to run in overlapping time periods. Synchronization ensures they do so correctly and safely.

These foundational concepts are the key to unlocking the power of modern computers. By managing access to shared data, we can build fast, responsive, and reliable software.