how to get the return value from a thread in python?
来源:互联网 发布:淘宝小商品推广免单 编辑:程序博客网 时间:2024/06/05 22:41
how to get the return value from a thread in python?
How can I access that return value 'foo' from the thread?
def foo(bar): print 'hello {0}'.format(bar) return 'foo'from threading import Threadt = Thread(target=foo, args=('world!',))t.start()x = t.join()print x
The one obvious way to do it, above, seems to just return None
in x.
5 Answers
FWIW, the multiprocessing
module has a nice interface for this using the Pool
class. And if you want to stick with threads rather than processes, you can just use themultiprocessing.pool.ThreadPool
class as a drop-in replacement.
def foo(bar, baz): print 'hello {0}'.format(bar) return 'foo' + bazfrom multiprocessing.pool import ThreadPoolpool = ThreadPool(processes=1)async_result = pool.apply_async(foo, ('world', 'foo')) # tuple of args for foo# do some other stuff in the main processreturn_val = async_result.get() # get the return value from your function.
One way I've seen is to pass a mutable object, such as a list or a dictionary, to the thread's constructor, along with a an index or other identifier of some sort. The thread can then store its results in its dedicated slot in that object. For example:
def foo(bar, result, index): print 'hello {0}'.format(bar) result[index] = "foo"from threading import Threadthreads = [None] * 10results = [None] * 10for i in range(len(threads)): threads[i] = Thread(target=foo, args=('world!', results, i)) threads[i].start()# do some other stufffor i in range(len(threads)): threads[i].join()print " ".join(results) # what sound does a metasyntactic locomotive make?
If you really want join()
to return the return value of the called function, you can do this with aThread
subclass like the following:
from threading import Threaddef foo(bar): print 'hello {0}'.format(bar) return "foo"class ThreadWithReturnValue(Thread): def __init__(self, group=None, target=None, name=None, args=(), kwargs={}, Verbose=None): Thread.__init__(self, group, target, name, args, kwargs, Verbose) self._return = None def run(self): if self._Thread__target is not None: self._return = self._Thread__target(*self._Thread__args, **self._Thread__kwargs) def join(self): Thread.join(self) return self._returntwrv = ThreadWithReturnValue(target=foo, args=('world!',))twrv.start()print twrv.join() # prints foo
That gets a little hairy because of some name mangling, and it accesses "private" data structures that are specific to Thread
implementation... but it works.
return
anything. i wanted to know in my original case, where does that 'foo' actually go...? – wim Aug 2 '11 at 3:53 Thread
, all that happens inside the class -- the default run()
method does not store off the return value, so you lose it. You could write your own Thread
subclass to handle this, though. I've taken a whack at it in my message. – kindall Aug 3 '11 at 1:20Jake's answer is good, but if you don't want to use a threadpool (you don't know how many threads you'll need, but create them as needed) then a good way to transmit information between threads is the built-inQueue.Queue class, as it offers thread safety.
I created the following decorator to make it act in a similar fashion to the threadpool:
def threaded(f, daemon=False): import Queue def wrapped_f(q, *args, **kwargs): '''this function calls the decorated function and puts the result in a queue''' ret = f(*args, **kwargs) q.put(ret) def wrap(*args, **kwargs): '''this is the function returned from the decorator. It fires off wrapped_f in a new thread and returns the thread object with the result queue attached''' q = Queue.Queue() t = threading.Thread(target=wrapped_f, args=(q,)+args, kwargs=kwargs) t.daemon = daemon t.start() t.result_queue = q return t return wrap
Then you just use it as:
@threadeddef long_task(x): import time x = x + 5 time.sleep(5) return x# does not block, returns Thread objecty = long_task(10)print y# this blocks, waiting for the resultresult = y.result_queue.get()print result
The decorated function creates a new thread each time it's called and returns a Thread object that contains the queue that will receive the result.
AttributeError: 'module' object has no attribute 'Lock'
this appears to be emanating from the line y = long_task(10)
... thoughts? – sadmicrowave Sep 13 at 2:26join
always return None
, i think you should subclass Thread
to handle return codes and so.
My solution to the problem is to wrap the function and thread in a class. Does not require using pools,queues, or c type variable passing. It is also non blocking. You check status instead. See example of how to use it at end of code.
import threadingclass ThreadWorker(): ''' The basic idea is given a function create an object. The object can then run the function in a thread. It provides a wrapper to start it,check its status,and get data out the function. ''' def __init__(self,func): self.thread = None self.data = None self.func = self.save_data(func) def save_data(self,func): '''modify function to save its returned data''' def new_func(*args, **kwargs): self.data=func(*args, **kwargs) return new_func def start(self,params): self.data = None if self.thread is not None: if self.thread.isAlive(): return 'running' #could raise exception here #unless thread exists and is alive start or restart it self.thread = threading.Thread(target=self.func,args=params) self.thread.start() return 'started' def status(self): if self.thread is None: return 'not_started' else: if self.thread.isAlive(): return 'running' else: return 'finished' def get_results(self): if self.thread is None: return 'not_started' #could return exception else: if self.thread.isAlive(): return 'running' else: return self.datadef add(x,y): return x +yadd_worker = ThreadWorker(add)print add_worker.start((1,2,))print add_worker.status()print add_worker.get_results()
- how to get the return value from a thread in python?
- Java How to get the PID from a process?
- How to remove the duplicated value in a String array
- Exception in thread "main" java.lang.IllegalStateException: Cannot get a text value from a numeric c
- How to write a shell script to check the return value of main()
- get the return value from the new activity
- return the minimum value in a stack
- How to Get a List of Class Attributes in Python
- How to get the default value in the paramter block description of 3ds max
- How to pass a value from User Control to the Page
- How to get parameters from the URL?
- How to get IHTMLDocument2 from a HWND
- flex/in the datagrid,how to get the new value of cell in the datagrid after edit
- How to get the DOM of a WebBrowser control from a window handle (VB6)
- Spring MVC How take the parameter value of a GET HTTP Request in my controller method?
- How to popup a UIPickerView from the bottom of a UIScrollView in response to UITextField selection
- How to access a value defined in the application.properties file in Spring Boot ( Externalized Conf)
- How to get the 2D coordinate of the max or min value in matrix in matlab
- Spring MVC 传递参数
- Linux平台下WebRTC音视频获取(Javascript API)
- 14-5(3)统计电话号码和QQ中同数字出现的个数
- WINDOW API基本屏幕绘图(GDI Graphics Device Interface 图像设备接口)
- MongoDB安装-CentOS
- how to get the return value from a thread in python?
- 将102011RAC升级到102040
- 搭建好Android开发环镜的Fedora15虚拟机
- perl滑动匹配核心代码
- Ibatis This SQL map does not contain a MappedStatement SelectAll 错误注意
- jsp 实现页面定时跳转
- 基于visual Studio2013解决C语言竞赛题之0601判断素数函数
- SQL的两种类型转换方式
- WinForm的RadioButton使用小技巧