Skip to content

Instantly share code, notes, and snippets.

@kleviscipi
Created October 18, 2019 10:52
Show Gist options
  • Select an option

  • Save kleviscipi/17d48261a1f4c82039d63fdcc953ae55 to your computer and use it in GitHub Desktop.

Select an option

Save kleviscipi/17d48261a1f4c82039d63fdcc953ae55 to your computer and use it in GitHub Desktop.
Resolve a race conditions example
from threading import Thread,Lock
"""
How ro resolve a Race Conditions in Python
Python is one of programming languages which support multiprocess and multi-threads and this is prety cool.
At the end python is not one of the best for parallel programming but lets see how we can use and resolve a common problem which is : Race Conditions
Before,I show you an example, first we should be familiar with this concept: Mutual Exlusion, Lock, Race Conditions
Mutual Exlusion ?: When tow or more processes/threads wants to access to a shared resources, and after thread has accessed that resource than block all others concurrent
Lock ?: A thread before accesses a shared resource, should graph or acquired a Lock,at this point all other councurrent are waiting for release of tha Lock.
Lock is released after thread has terminated it's eczecution time using that resource.
Race Conditions: The mutual exlusion comes out for this purpose, to resolve race conditions.
A race condition happens when tow or more parallel threads has accessed at the same time and updated a shared resource, that's mind it is not protected by a lock.
"""
# x = 1 # Shared resource
# def fibonaci(n):
# if n<=2 : return 1
# return fibonaci(n-1) + fibonaci(n-2)
# def firstFibonaci():
# global x
# print("firstFibonaci resource is {} \n".format(x) )
# while x <= 10:
# print(fibonaci(x))
# x+=1
# def secondFibonaci():
# global x
# print("secondFibonaci resource is {} \n".format(x) )
# while x <= 10:
# print(fibonaci(x))
# x+=1
# Parallel_1 = Thread(target=firstFibonaci)
# Parallel_2 = Thread(target=secondFibonaci)
# Parallel_1.start()
# Parallel_2.start()
# Parallel_1.join()
# Parallel_2.join()
"""
I have created tow methods firstFibonaci and secondFibonaci and on each one, the shared resource x is in global scope. The shared resource is x and will be accessed by threads in parallel
Technically the second method should not make any update to the shared resource, because it is incremented to 11 by the firstFibonaci method, but is it?
This is the expected correct response
$ /usr/bin/python race_condition.py
firstFibonaci resource is 1
1
1
2
3
5
8
13
21
34
55
secondFibonaci resource is 11
But se how really is the response :
$ /usr/bin/python race_condition.py
firstFibonaci resource is 1
1
secondFibonaci resource is 1
1
12
35
8
13
34
2155
or another
$ /usr/bin/python race_condition.py
firstFibonaci resource is 1
1
1
2
3
5
secondFibonaci resource is 6
88
13
2134
55
Why is happened that?
That because the shared resource x is not protected by a Lock. Tow threads at the same time have accessed to that resource updating the state.
Now, to resolve this race condition we go to use anther class of packet threading which is Lock. 
This class has tow main method :
acquire: That means , the lock is graphed by a thread and all concurrent are blocked waiting for the release.
release: That means, the lock is free ready for another thread.
"""
x = 1 # Shared resource
lock_race = Lock()
def fibonaci(n):
if n<=2 : return 1
return fibonaci(n-1) + fibonaci(n-2)
def firstFibonaci():
global x
try:
lock_race.acquire()
print("firstFibonaci resource is {} \n".format(x) )
while x <= 10:
print(fibonaci(x))
x+=1
finally:
lock_race.release()
def secondFibonaci():
global x
try:
lock_race.acquire()
print("secondFibonaci resource is {} \n".format(x) )
while x <= 10:
print(fibonaci(x))
x+=1
finally:
lock_race.release()
Parallel_1 = Thread(target=firstFibonaci)
Parallel_2 = Thread(target=secondFibonaci)
Parallel_1.start()
Parallel_2.start()
Parallel_1.join()
Parallel_2.join()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment