Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I access data from a python thread

I have a very simple threading example using Python 3.4.2. In this example I am creating a five threads that just returns the character string "Result" and appends it to an array titled thread. In another for loop iterated five times the threads are joined to the term x. I am trying to print the result x, which should yield a list that looks like ['Resut','Result','Result','Result','Result'] but instead the print command only yields the title of the thread and the fact that it is closed. Im obviously misunderstanding how to use threads in python. If someone could provide an example of how to adequately complete this test case I would be very grateful.

 import threading

 def Thread_Test():
     return ("Result")

 number  = 5
 threads = []
 for i in range(number):
     Result = threading.Thread(target=Thread_Test)
     threads.append(Result)
     Result.start()

 for x in threads:
     x.join()
 print (x)
like image 889
Jon Avatar asked Mar 09 '17 15:03

Jon


People also ask

How do you retrieve data from a thread in Python?

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 Thread threads = [None] * 10 results = [None] * 10 for i in range(len(threads)): threads[i] = Thread(target=foo, args=('world!

How do you return a value from a thread?

There are two main ways to return values from a thread, they are: Extend threading. Thread and store data in instance variables. Store data in global variables.

How do you communicate data between threads?

Perhaps the safest way to send data from one thread to another is to use a Queue from the queue library. To do this, create a Queue instance that is shared by the threads. Threads then use put() or get() operations to add or remove items from the queue as shown in the code given below.


1 Answers

There is a difference between creating a thread and trying to get values out of a thread. Generally speaking, you should never try to use return in a thread to provide a value back to its caller. That is not how threads work. When you create a thread object, you have to figure out a different way of get any values calculated in the thread to some other part of your program. The following is a simple example showing how values might be returned using a list.

#! /usr/bin/env python3
import threading


def main():
    # Define a few variables including storage for threads and values.
    threads_to_create = 5
    threads = []
    results = []
    # Create, start, and store all of the thread objects.
    for number in range(threads_to_create):
        thread = threading.Thread(target=lambda: results.append(number))
        thread.start()
        threads.append(thread)
    # Ensure all threads are done and show the results.
    for thread in threads:
        thread.join()
    print(results)


if __name__ == '__main__':
    main()

If you absolutely insist that you must have the ability to return values from the target of a thread, it is possible to override some methods in threading.Thread using a child class to get the desired behavior. The following shows more advanced usage and demonstrates how multiple methods require a change in case someone desires to inherit from and override the run method of the new class. This code is provided for completeness and probably should not be used.

#! /usr/bin/env python3
import sys as _sys
import threading


def main():
    # Define a few variables including storage for threads.
    threads_to_create = 5
    threads = []
    # Create, start, and store all of the thread objects.
    for number in range(threads_to_create):
        thread = ThreadWithReturn(target=lambda: number)
        thread.start()
        threads.append(thread)
    # Ensure all threads are done and show the results.
    print([thread.returned for thread in threads])


class ThreadWithReturn(threading.Thread):

    def __init__(self, group=None, target=None, name=None,
                 args=(), kwargs=None, *, daemon=None):
        super().__init__(group, target, name, args, kwargs, daemon=daemon)
        self.__value = None

    def run(self):
        try:
            if self._target:
                return self._target(*self._args, **self._kwargs)
        finally:
            del self._target, self._args, self._kwargs

    def _bootstrap_inner(self):
        try:
            self._set_ident()
            self._set_tstate_lock()
            self._started.set()
            with threading._active_limbo_lock:
                threading._active[self._ident] = self
                del threading._limbo[self]

            if threading._trace_hook:
                _sys.settrace(threading._trace_hook)
            if threading._profile_hook:
                threading. _sys.setprofile(threading._profile_hook)

            try:
                self.__value = True, self.run()
            except SystemExit:
                pass
            except:
                exc_type, exc_value, exc_tb = self._exc_info()
                self.__value = False, exc_value
                if _sys and _sys.stderr is not None:
                    print("Exception in thread %s:\n%s" %
                          (self.name, threading._format_exc()), file=_sys.stderr)
                elif self._stderr is not None:
                    try:
                        print((
                            "Exception in thread " + self.name +
                            " (most likely raised during interpreter shutdown):"), file=self._stderr)
                        print((
                            "Traceback (most recent call last):"), file=self._stderr)
                        while exc_tb:
                            print((
                                '  File "%s", line %s, in %s' %
                                (exc_tb.tb_frame.f_code.co_filename,
                                    exc_tb.tb_lineno,
                                    exc_tb.tb_frame.f_code.co_name)), file=self._stderr)
                            exc_tb = exc_tb.tb_next
                        print(("%s: %s" % (exc_type, exc_value)), file=self._stderr)
                    finally:
                        del exc_type, exc_value, exc_tb
            finally:
                pass
        finally:
            with threading._active_limbo_lock:
                try:
                    del threading._active[threading.get_ident()]
                except:
                    pass

    @property
    def returned(self):
        if self.__value is None:
            self.join()
        if self.__value is not None:
            valid, value = self.__value
            if valid:
                return value
            raise value


if __name__ == '__main__':
    main()
like image 155
Noctis Skytower Avatar answered Sep 23 '22 02:09

Noctis Skytower