user3467349
user3467349

Reputation: 3191

Python: Using RLock with multiple threads

The expected output should be for all 3 func() processes to complete and for 'finished' to not be printed, but instead test() returns finished after the first print(i) in func().

rlock = threading.RLock()

def func(): 
    rlock.acquire()
    for i in range(3): 
        time.sleep(2)
        print(i)
    rlock.release()
    return

def test(): 
    l = []
    for i in range(3): 
        time.sleep(1)
        threading.Thread(target=func).start() 
    print(rlock) # prints <_thread.RLock owner=140092805895936 count=1>
    print(rlock._is_owned()) #prints False 
    if not rlock._is_owned(): 
        return 'finished' #returns 'finished'

test()

Update: specifically I would like to have a test() function that does not return until all threads in rlock are finished. But I'm having trouble determining whether the rlock counter is incremented or not - there doesn't seem to be a method corresponding to that.

Upvotes: 0

Views: 437

Answers (1)

tdelaney
tdelaney

Reputation: 77357

When using ill-defined internal functions like _is_owned, its best to look at the source:

def _is_owned(self):
    # Return True if lock is owned by current_thread.
    # This method is called only if __lock doesn't have _is_owned().

The main thread doesn't own the lock so the function returns false.

Update

If you just want to wait for the threads to finish, you don't need an RLock object at all. Just use the join() method:

def func(): 
    for i in range(3): 
        time.sleep(2)
        print(i)
    return

def test(): 
    threads = []
    for i in range(3): 
        time.sleep(1)
        thread = threading.Thread(target=func)
        thread.start()
        threads.append(thread)
    for thread in threads:
        thread.join()
    return 'finished'

test()

Upvotes: 1

Related Questions