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'
asked Oct 11, 2015 at 2:07
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.

answered Oct 11, 2015 at 4:30
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

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

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.