I was learning and testing threading
in python, and Lock
class, So in here I want to add a key to persons
but let's say it will takes some time, in another thread I want to read the key. in first thread I should lock the process but I still get an error.
import threading
from time import sleep
persons = {
"test": "test",
"test2": "test2",
}
lock = threading.Lock()
def func1():
global persons
lock.acquire()
sleep(10)
persons["test3"] = "test3"
lock.release()
def func2():
global persons
print(persons["test3"])
t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
t2.join()
t1.join()
I lock the func1()
but still get error:
Traceback (most recent call last):
File "c:\Users\p.riahi\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 1038, in _bootstrap_inner
self.run()
File "c:\Users\p.riahi\AppData\Local\Programs\Python\Python311\Lib\threading.py", line 975, in run
self._target(*self._args, **self._kwargs)
File "c:\Users\p.riahi\Desktop\temp\thred.py", line 20, in func2
print(persons["test3"])
~~~~~~~^^^^^^^^^
KeyError: 'test3'
Can anyone help me what I misunderstand here, the func1()
should have locked the persons
but it's not.
If thread t2 runs before thread t1 acquires the lock and adds "test3", t2.join() might cause the main thread to wait for t2 to finish even though there's no "test3" key yet in the dictionary. This could lead to a KeyError exception.
So, you should lock the person inside function2 and release it after read the person. I have modified the code, you can use it.
import threading
from time import sleep
persons = {
"test": "test",
"test2": "test2",
}
lock = threading.Lock()
def func1():
global persons
lock.acquire()
sleep(10)
persons["test3"] = "test3"
lock.release()
# def func2():
# global persons
# print(persons["test3"])
def func2():
global persons
lock.acquire()
try:
value = persons["test3"] # Attempt to get the value
print(value)
except KeyError: # Handle case where key doesn't exist
print("Key 'test3' not found in the dictionary")
finally:
lock.release()
t1 = threading.Thread(target=func1)
t2 = threading.Thread(target=func2)
t1.start()
t2.start()
t2.join()
t1.join()