Threading the same function for a different result in Python -
i need program execute function in parallel. function branches off different results depending on how user interacts program. have simple gui within module named threadgui.py has 2 options: downloading , uploading. these options create dictionaries containing variables related function. these dictionaries stored in main dictionary stored in thread_test.py module. these work fine when executing 1 after other, when try in parallel goes wrong. threading related code in threadgui.py:
def onstartclick(self): in thread_test.dictlist.values(): #the main dictionary stored global in thread_test.py thread = thread(target = thread_test.begin_tests, args = (i, )) thread.start() print "thread finished...exiting" the above function calls begin_test function within thread_test.py module. function looks so:
def begin_tests(arg): print arg print dictlist dictitem = arg print dictitem if dictitem['type'] == "http_downloading": print "download" elif dictitem['type'] == "ftp_uploading": print "upload" else: print "invalid input" sys.exit(1) this simplified example of code. problem code executing 1 function out of 2 instead of both. if created dictionary called download, upload, download execute 3 downloads, instead of desired pattern.
the problem not in code posted:
from threading import thread dictlist = { 'foo': { 'type': 'http_downloading' }, 'bar': { 'type': 'ftp_uploading' }, 'baz': { 'type': 'http_downloading' } } def begin_tests(arg): print arg print dictlist dictitem = arg print dictitem if dictitem['type'] == "http_downloading": print "download" elif dictitem['type'] == "ftp_uploading": print "upload" else: print "invalid input" sys.exit(1) def onstartclick(self): in dictlist.values(): #the main dictionary stored global in thread_test.py thread = thread(target = begin_tests, args = (i, )) thread.start() print "thread finished...exiting" onstartclick(none) results in:
{'type': 'http_downloading'} {'baz': {'type': 'http_downloading'}, 'foo': {'type': 'http_downloading'}, 'bar': {'type': 'ftp_uploading'}} {'type': 'http_downloading'} {download {'type': 'ftp_uploading'} 'type': 'http_downloading'} {'baz': {'type': 'http_downloading'}, 'foo': {'type': 'http_downloading'}, 'bar': {'type': 'ftp_uploading'}} {'baz': {'type': 'http_downloading'}, 'foo': {'type': 'http_downloading'}, 'bar': {'type': 'ftp_uploading'}} thread finished...exiting {'type': 'http_downloading'} download {'type': 'ftp_uploading'} upload at guess, reusing inner dict.
update:
i think case better solved using worker-pool-and-queue strategy. like:
from queue import queue threading import thread queue = queue() # replaces dictlist threads = [] n in range(10): thread = thread(target = worker, args = (begin_tests, queue, )) thread.start() threads.append(thread) stop = object() def worker(work, queue): while true: task = queue.get() if task stop: break work(task) use so:
queue.put({ 'type': 'http_downloading' }) queue.put({ 'type': 'ftp_uploading' }) queue.put({ 'type': 'http_downloading' }) queue.put(stop) this not in address problem of mutating dicts; has fixed elsewhere. strategy has 2 benefits: preserve order of tasks , not risk losing tasks: dict makes limited concurrency guarantees, whereas queue() guaranteed thread-safe.
Comments
Post a Comment