0

I am messing around with threading, and I am trying to understand the concept of thread locks.So let me review a little bit the theory just to check if I understood it correctly.

Theory

So sometimes threads, even though they are cool, can make some pretty bad stuff.Sometimes we want to modify a global variable, but if the order matters, we cannot have two threads work at the same time.My first question is: in case we wanted this behaviour, couldn’t we just opt for synchronous programming?Let’s move on. Basically, the first thing we need to so is to call threading.Lock().To be honest I do not know why we need to call this function.Could someone explain it?The second thing is to create all the needed threads and start them up.Let me call them thread_1 and thread_2:

if __name__ == '__main__':
    thread_1 = threading.Thread(name="THREAD 1", target=add_to_employee)
    thread_2 = threading.Thread(name="THREAD 2", target=take_from_employee)
    thread_1.start()
    thread_2.start()

Then we can create the target functions, that are going to be targetted by the two functions.SMALL QUESTION:I have used the word targetted, but I would have liked to use the word “controlled”, this is possible right because the thread and only the thread has control on the targetted function, right?

Now come the actual problems that I am facing: What I really want to understand is the intaction between these three methods .join(),.acquire()`,.release()

Practice

First I call the two thread methods
thread_1.start()
thread_2.start()

Now both threads run concurrently

Now question look at this code


def add_to_employee():
    global bill
    for i in range(10):
        lock.acquire()
        bill += 10
        print(f"thread_working: {thread_1.name}")
        #time.sleep(1)
        lock.release()


def take_from_employee():
    global bill
    for i in range(10):
        lock.acquire()
        bill -= 10
        print(f"thread_working: {thread_2.name}")
        # time.sleep(5)
        lock.release()
if __name__ == '__main__':
    thread_1 = threading.Thread(name="THREAD 1", target=add_to_employee)
    thread_2 = threading.Thread(name="THREAD 2", target=take_from_employee)
    thread_1.start()
    thread_2.start()
    #thread_1.join()
    #thread_2.join()
    print("All finished")
    print(bill)

If I do not use the lock methods then the code crashes. The two threads mix and the output is completely messed up.Shouldn’t .join alone wait for a thread to finish? But if I use the lock.acquire() and the lock.release() methods without join then we are going to run first thread_1 and then thread_2.What are the differences between the .join method and the functionalities of this lock object.Could you elaborate a little bit more on this lock method?

Last question

Can you see the uncommented time.sleep() function?If I put it there the thread seems to not be locked anymore, or maybe it is locked, and then releases and for the next five seconds the other threads work.Actually, I have no idea. Sorry for asking all this questions but to be honest, I could not find any exhaustive resource.Thank you for your time.
  • Re, "trying to understand...thread locks." Just in case the answers on the "duplicate" don't do it for you: The reason _why_ you want a mutex (a.k.a., "thread lock") is to ensure that different threads always see shared data in some consistent/valid state. Say your program has several global variables that all must "agree" with each other. Since a thread can only assign variables one-by-one, there's no way to change the shared state without _temporarily_ putting it into an inconsistent/invalid state. The real purpose of mutex locks is to ensure that no other thread can see that bad state. – Solomon Slow Oct 04 '21 at 18:51

0 Answers0