Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help

Hand-drawn figure showing threads racing to achieve a task.In the programming world there might be a situation where you need to set up a Binary Condition (True or False), the condensed way is to declare a global Boolean and use that in conditional sta…


This content originally appeared on Level Up Coding - Medium and was authored by Milad khormaee

Hand-drawn figure showing threads racing to achieve a task.

In the programming world there might be a situation where you need to set up a Binary Condition (True or False), the condensed way is to declare a global Boolean and use that in conditional statements, this is a plain sailing approach, but it’s not the ideal approach as your program grows. While multithreading and multiprocessing can provide substantial performance benefits, they demand careful consideration of thread safety to avoid sudden bugs. Ignoring them can have serious consequences in later use cases.

In this article, I’ll introduce what is a race condition and why it could happen in multithreading and present a solution for it.

Before I dive into the example, I’d like to mention shortly about the differences between Multithreading and Multiprocessing to make the comprehension easier :

Multithreading uses multiple threads within a single process, sharing the same memory space, while multiprocessing uses multiple processes, each with its own independent memory space

What is a Race Condition?

A race condition happens when several threads try to read and modify the same piece of shared data simultaneously. In simpler word, they’re “racing” to access and change the data.

In this scenario I’ll talk about multithreading which, we can simulate a real race condition using the multiprocessing module, which gives us real concurrent processes.

For instance, consider example below which simulate a race condition program, tries to compute Fibonacci example up to 10 by dividing works between two threads

from threading import Thread
import time

x = 1
stop_flag = False # Not thread-safedef fib(n):
if n <= 2: return 1
return fib(n - 1) + fib(n - 2)
def compute_fib(name):
global x, stop_flag
while not stop_flag and x <= 10:
print(f"{name} -> fib({x}) = {fib(x)}")
x += 1 # Race condition here
time.sleep(0.01)
if x > 10:
stop_flag = True # Race condition here too
t1 = Thread(target=compute_fib, args=("Thread-1",))
t2 = Thread(target=compute_fib, args=("Thread-2",))
t1.start()
t2.start()
t1.join()
t2.join()

Output:

Thread-1 -> fib(1) = 1
Thread-2 -> fib(2) = 1
Thread-1 -> fib(3) = 2
Thread-2 -> fib(4) = 3
Thread-1 -> fib(5) = 5
Thread-2 -> fib(5) = 5
Thread-1 -> fib(7) = 13
Thread-2 -> fib(7) = 13
Thread-1 -> fib(9) = 34
Thread-2 -> fib(10) = 55

We can notice that fib(7) has run twice, and there is no sign of fib(8).

  • x += 1 is not atomic. Threads can read and update x at the same time.
  • There are signs of duplicated and missing values.
  • Why? Because the flag change was not accessible to the other threads. This approach is not thread-safe and might be cached (one thread doesn’t see updates). This is an example of what we call race condition.

Flags like stop = False aren’t thread-safe by default. If two threads (e.g., one for working and one for listening to input) try to read/write the same variable, they could:

  • Cause race conditions (one changes the flag before the other reads it)
  • Busy waiting or inefficient waiting: The worker loop must keep checking the flag repeatedly, which can waste CPU cycles or cause delays.
An example of Fibonacci race condition sequence diagram.

Now that we’ve seen how race conditions occurs due to unsynchronized access to shared state, let’s look at a thread-safe alternative using Python’s threading.Event module. This class allows threads to communicate through a shared flag that is, by default, synchronized — unlike a plain Boolean. Combined with locking when shared data is being updated, this approach helps us effectively tackle race conditions while still benefiting from the advantages of concurrent processing.

Here’s the improved version of the Fibonacci example by incorporating Event and lock mechanism:

from threading import Thread, Event, Lock
import time

x = 1
stop_signal = Event() # Using Event Rather than bolean
lock = Lock()

def fib(n):
if n <= 2: return 1
return fib(n - 1) + fib(n - 2)

def compute_fib(name):
global x
while not stop_signal.is_set(): # Checking if signal is set (True)
with lock: # Locking the threads while updating the value
if x > 10:
stop_signal.set()
break
print(f"{name} -> fib({x}) = {fib(x)}")
x += 1
time.sleep(0.01)

t1 = Thread(target=compute_fib, args=("Thread-1",))
t2 = Thread(target=compute_fib, args=("Thread-2",))

t1.start()
t2.start()
t1.join()
t2.join()

Output:

Thread-1 -> fib(1) = 1
Thread-2 -> fib(2) = 1
Thread-1 -> fib(3) = 2
Thread-2 -> fib(4) = 3
Thread-1 -> fib(5) = 5
Thread-2 -> fib(6) = 8
Thread-1 -> fib(7) = 13
Thread-2 -> fib(8) = 21
Thread-1 -> fib(9) = 34
Thread-2 -> fib(10) = 55

Now we can observe that the Fibonacci function is working correctly with multiple threads, let’s review what we’ve changed:

  • Replaced the Boolean flag with threading.Event : Which is designed for thread-safe signaling. When one thread sets the signal, all other threads can confidentially observe the changes without risk of inconsistent reads.
  • Using Lock mechanism: The lock ensures that the critical section such as, accessing and incrementing the shared variable in this case x to be only executed by one thread at a time. This prevents overlap, duplication, or missing values.

📝 Conclusion:

By combining Event and Lock, we’ve not only eliminated the race condition but also preserved the benefits of concurrent execution. This structure is much more efficient and scalable, especially when the logic becomes more complex or when multiple resources are being shared across threads.

If you found this article helpful, don’t forget to hit the clap button 👏

I certainly appreciate your support 🙏

Resources:


Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help was originally published in Level Up Coding on Medium, where people are continuing the conversation by highlighting and responding to this story.


This content originally appeared on Level Up Coding - Medium and was authored by Milad khormaee


Print Share Comment Cite Upload Translate Updates
APA

Milad khormaee | Sciencx (2025-06-09T17:03:34+00:00) Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help. Retrieved from https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/

MLA
" » Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help." Milad khormaee | Sciencx - Monday June 9, 2025, https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/
HARVARD
Milad khormaee | Sciencx Monday June 9, 2025 » Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help., viewed ,<https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/>
VANCOUVER
Milad khormaee | Sciencx - » Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help. [Internet]. [Accessed ]. Available from: https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/
CHICAGO
" » Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help." Milad khormaee | Sciencx - Accessed . https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/
IEEE
" » Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help." Milad khormaee | Sciencx [Online]. Available: https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/. [Accessed: ]
rf:citation
» Why Flags Can Cause Race Conditions in Multithreading, and How Events Can Help | Milad khormaee | Sciencx | https://www.scien.cx/2025/06/09/why-flags-can-cause-race-conditions-in-multithreading-and-how-events-can-help/ |

Please log in to upload a file.




There are no updates yet.
Click the Upload button above to add an update.

You must be logged in to translate posts. Please log in or register.