0

The queueLock.acquire() line hangs a code that tries to take advantage of threading and Queue modules with following output:

run() on <newThread(Thread-1, started 4344102912)>

run() on <newThread(Thread-2, started 4348309504)>

...working delay: 1

Why?

import threading, thread, Queue, time

class newThread (threading.Thread):
    def __init__(self, delay=0, workQueue=None):
        self.delay=delay
        self.workQueue=workQueue
        threading.Thread.__init__(self)

    def run(self):
        print '\nrun() on %s'%self
        print_time(self.delay, self.workQueue)
        print '\nrun() exit %s'%self

def print_time(delay=None, workQueue=None):
    def onExit():
        if not workQueue.empty():
            data = workQueue.get()
            queueLock.release()
        else:
            queueLock.release()

    counter=0
    while True:
        queueLock.acquire()
        time.sleep(delay)
        print '\t...working delay: %s'%delay   

        if counter>5:
            onExit()

        counter=counter + 1



queueLock = threading.Lock()
workQueue = Queue.Queue(10)
threads = []

thread1 = newThread(delay=1, workQueue=workQueue)
thread1.start()
threads.append(thread1)

thread2 = newThread(delay=2, workQueue=workQueue)
thread2.start()
threads.append(thread2)

queueLock.acquire()
print '1. workQueue.empty():',workQueue.empty()
workQueue.put('One')
print '2. workQueue.empty():',workQueue.empty()
workQueue.put('Two')

queueLock.release()

#Wait for queue to empty
while not workQueue.empty():
    print '...passing while not workQueue.empty()'
    pass

for thread in threads:
    thread.join()

print '...completed'
5
  • 1
    Error message and stack trace would be very helpful. It would also help to show what the output is (i.e. which of your print lines actually executed) Commented Oct 11, 2015 at 2:20
  • Are you running standard C-based Python? If so, you can't do multithreading in the traditional sense. Look at the GIL Commented Oct 11, 2015 at 2:44
  • 1
    @Tyler: GIL has nothing to do with it. Commented Oct 11, 2015 at 4:23
  • Some suggestions for your code: You don't have to derive from Thread, you can simply run any function with a plain Thread instance. It would also help if you didn't specify default parameters for functions where they may no sense at all, like passing None as queue to print_time(). Also, upgrade to Python 3! Commented Oct 11, 2015 at 8:15
  • Please post some example on how to run any function with a plain Thread instance. Commented Oct 14, 2015 at 3:58

1 Answer 1

2

queueLock.acquire() blocks until queueLock.release() is called if queueLock is already acquired. counter > 5 never happens because even if queueLock is available on the first iteration of the loop; nothing releases it on the 2nd iteration.

Queue() has its own locks. Drop queueLock completely.

Sign up to request clarification or add additional context in comments.

1 Comment

I'd like to add that in order to not forget releasing a lock, you can use it as context manager, i.e. with some_lock.acquire(): ....

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.