I am working on a Monte Carlo simulation. The simulation uses many runs that are independent of each other, so it seems like multi-threading is appropriate.
I've never used threading before, so this is my first try. For starters, I wrote a simple script just to see if I can get it to work.
I read Python docs for modules threading and Queue. I also looked up a couple examples, but they didn't help me much.
Here is the script I wrote:
Code:
import threading
import time
runprmque = [(1, 2), (3, 4), (5, 6), (7, 8)]
threadmax = 3 #limit the number of simultaneous threads
threads = [] #list of current threads
def f(x, y): #work function called by the threads
time.sleep(x+y)
print x + y
return None
while len(runprmque) > 0 or len(threads) > 0:
#runs until all threads finish and no more jobs are left
while len(threads) < threadmax and len(runprmque) > 0:
#find available thread slots and fill them with unfinished jobs
t = threading.Thread(target = f, args = runprmque[0])
print 'Job assigned: ' + str(runprmque[0]) + ' to ' + t.name
t.start()
del runprmque[0]
threads.append(t)
del t
n = 0
while n < len(threads):
#remove threads that have finished
if threads[n].is_alive():
n = n + 1
else:
print 'Removing thread: ' + threads[n].name
del threads[n]
When the print statement in f() is enabled, it produces orderly output:
Code:
Job assigned: (1, 2) to Thread-1
Job assigned: (3, 4) to Thread-2
Job assigned: (5, 6) to Thread-3
3
Removing thread: Thread-1
Job assigned: (7, 8) to Thread-4
7
Removing thread: Thread-2
11
Removing thread: Thread-3
15
Removing thread: Thread-4
But when it is disabled, the output becomes garbled:
Code:
Job assigned: (1, 2) to Thread-1
3Job assigned: (3, 4) to Thread-2
7Job assigned: (5, 6) to Thread-3
11Removing thread: Thread-1
Removing thread: Thread-2
Removing thread: Thread-3
Job assigned: (7, 8) to Thread-4
15
Removing thread: Thread-4
I am assuming this is because multiple threads are trying to interact with the main thread at the same time, and everything gets confusing. How can I keep the threads from piling on top of each other? In the realistic application, I won't know which job will finish first, so I can't just use .join() to keep things in order.
I am working in Python 2.7.2 64-bit on Windows 7, with a dual-core Intel.
Bookmarks