user19551894
user19551894

Reputation:

Unexpected output with Lock.acquire() and Lock.release()

from threading import Thread
import threading
import time


def procesa1():
    lock = threading.Lock()
    lock.acquire()

    for i in range(3):
        print(threading.get_ident())
    lock.release()


if __name__ == "__main__":
    hilos = []
    for i in range(5):
        hilos.append(Thread(target=procesa1))
    for thread in hilos:
        thread.start()

The 3 print in each thread should come out in a row, shouldn't they?

A thread WINS the lock, prints its 3 outputs in a row (not interspersed with those of the other threads) and then the 3 outputs of the next thread.

This is an example of the multiple random outputs:

13108
13108
13108
12780
12780
12780
7756 // what?
6844
6844
6844
7756 // what?
7756 // what?
11936 //good
11936 //good
11936 //good, they are consecutive

The lock is supposed to be for a critical "atomic" section accessed by one thread AT A TIME.

What am I losing?

Upvotes: 0

Views: 48

Answers (1)

sj95126
sj95126

Reputation: 6908

The lock doesn't help to synchronize threads because each thread is creating its own lock. You need to create a single lock and pass it as an argument to each thread, so they can share it.

This works as expected (I simplified the syntax using with):

def procesa1(lock):
    with lock:
        for i in range(3):
            print(threading.get_ident())


if __name__ == "__main__":
    lock = threading.Lock()
    hilos = []
    for i in range(5):
        hilos.append(Thread(target=procesa1, args=(lock,)))
    for thread in hilos:
        thread.start()

Output:

34360446720
34360446720
34360446720
34360360224
34360360224
34360360224
[....]

Upvotes: 1

Related Questions