在 Python 中,如何让线程将元组或我选择的任何值返回给父级?

有帮助吗?

解决方案

我建议你实例化一个 Queue.Queue 之前启动线程,并把它作为该线程的ARGS之一:线程完成之前,它.puts它作为参数接收的队列的结果。父进程可以.get或随意.get_nowait它。

队列一般都安排在Python线程同步和通信的最佳途径:他们本质上是线程安全的,消息传递车辆 - 组织一般多任务的最佳途径 - )

其他提示

如果你调用join()等待线程完成,你可以简单地将结果附加到线程实例本身,然后加入()返回后,从主线程获取它。

在另一方面,你不告诉我们你打算如何发现线程完成并且结果是可用的。如果你已经有这样做的一种方式,它可能会指向你(和我们,如果你要告诉我们)得到的结果出来的最佳方式。

您应该传递一个 Queue 实例作为参数,然后您应该将返回对象 .put() 放入队列中。无论您放置什么对象,您都可以通过queue.get()收集返回值。

样本:

queue = Queue.Queue()
thread_ = threading.Thread(
                target=target_method,
                name="Thread1",
                args=[params, queue],
                )
thread_.start()
thread_.join()
queue.get()

def target_method(self, params, queue):
 """
 Some operations right here
 """
 your_return = "Whatever your object is"
 queue.put(your_return)

用于多线程:

#Start all threads in thread pool
    for thread in pool:
        thread.start()
        response = queue.get()
        thread_results.append(response)

#Kill all threads
    for thread in pool:
        thread.join()

我使用这个实现,它对我来说非常有用。我希望你这样做。

使用的拉姆达以包住目标线程的功能和使用的队列传递它的返回值返回给父线程即可。 (你的原始目标函数仍没有额外的队列参数不变。)

样品的编号:

import threading
import queue
def dosomething(param):
    return param * 2
que = queue.Queue()
thr = threading.Thread(target = lambda q, arg : q.put(dosomething(arg)), args = (que, 2))
thr.start()
thr.join()
while not que.empty():
    print(que.get())

输出:

4

我很惊讶没有人提到,你可以只通过它一个可变的:

>>> thread_return={'success': False}
>>> from threading import Thread
>>> def task(thread_return):
...  thread_return['success'] = True
... 
>>> Thread(target=task, args=(thread_return,)).start()
>>> thread_return
{'success': True}

也许这具有的,我不知道的重大问题。

另一种方法是一个回调函数传递给线程。这给出了一个简单,安全和灵活的方式将数值从新线程返回到父,随时随地。

# A sample implementation

import threading
import time

class MyThread(threading.Thread):
    def __init__(self, cb):
        threading.Thread.__init__(self)
        self.callback = cb

    def run(self):
        for i in range(10):
            self.callback(i)
            time.sleep(1)


# test

import sys

def count(x):
    print x
    sys.stdout.flush()

t = MyThread(count)
t.start()

可以使用同步队列的模块。结果 想想你需要检查从数据库中的用户的相关信息与已知的ID:

def check_infos(user_id, queue):
    result = send_data(user_id)
    queue.put(result)

现在,你可以得到你的数据是这样的:

import queue, threading
queued_request = queue.Queue()
check_infos_thread = threading.Thread(target=check_infos, args=(user_id, queued_request))
check_infos_thread.start()
final_result = queued_request.get()

POC:

import random
import threading

class myThread( threading.Thread ):
    def __init__( self, arr ):
        threading.Thread.__init__( self )
        self.arr = arr
        self.ret = None

    def run( self ):
        self.myJob( self.arr )

    def join( self ):
        threading.Thread.join( self )
        return self.ret

    def myJob( self, arr ):
        self.ret = sorted( self.arr )
        return

#Call the main method if run from the command line.
if __name__ == '__main__':
    N = 100

    arr = [ random.randint( 0, 100 ) for x in range( N ) ]
    th = myThread( arr )
    th.start( )
    sortedArr = th.join( )

    print "arr2: ", sortedArr

那么,Python的线程模块中,但是也有一些关联到锁状态的对象。一种方法acquire()将返回任何值从底层方法返回。有关详细信息: Python的条件对象

根据jcomeau_ictx的建议。最简单的一个,我碰到。这里的要求是从服务器上运行的三种不同的工艺获得退出状态状况 - 触发另一个脚本,如果所有三个都成功。这似乎是工作细

  class myThread(threading.Thread):
        def __init__(self,threadID,pipePath,resDict):
            threading.Thread.__init__(self)
            self.threadID=threadID
            self.pipePath=pipePath
            self.resDict=resDict

        def run(self):
            print "Starting thread %s " % (self.threadID)
            if not os.path.exists(self.pipePath):
            os.mkfifo(self.pipePath)
            pipe_fd = os.open(self.pipePath, os.O_RDWR | os.O_NONBLOCK )
           with os.fdopen(pipe_fd) as pipe:
                while True:
                  try:
                     message =  pipe.read()
                     if message:
                        print "Received: '%s'" % message
                        self.resDict['success']=message
                        break
                     except:
                        pass

    tResSer={'success':'0'}
    tResWeb={'success':'0'}
    tResUisvc={'success':'0'}


    threads = []

    pipePathSer='/tmp/path1'
    pipePathWeb='/tmp/path2'
    pipePathUisvc='/tmp/path3'

    th1=myThread(1,pipePathSer,tResSer)
    th2=myThread(2,pipePathWeb,tResWeb)
    th3=myThread(3,pipePathUisvc,tResUisvc)

    th1.start()
    th2.start()
    th3.start()

    threads.append(th1)
    threads.append(th2)
    threads.append(th3)

    for t in threads:
        print t.join()

    print "Res: tResSer %s tResWeb %s tResUisvc %s" % (tResSer,tResWeb,tResUisvc)
    # The above statement prints updated values which can then be further processed

下面的包装函数将包装的现有功能,并返回一个指向既给线程的对象(这样就可以调用start()join()等就可以了),以及访问/查看其最终返回值。

def threadwrap(func,args,kwargs):
   class res(object): result=None
   def inner(*args,**kwargs): 
     res.result=func(*args,**kwargs)
   import threading
   t = threading.Thread(target=inner,args=args,kwargs=kwargs)
   res.thread=t
   return res

def myFun(v,debug=False):
  import time
  if debug: print "Debug mode ON"
  time.sleep(5)
  return v*2

x=threadwrap(myFun,[11],{"debug":True})
x.thread.start()
x.thread.join()
print x.result

这看起来不错,和threading.Thread类似乎很容易扩展(*)具有这种功能,所以我不知道为什么它已不存在。是否有与上述方法的缺陷?

(*)请注意,husanu对这个问题的答案正是这样做的,继承导致的版本,其中threading.Thread给出的返回值join()

为了便于程序以上答案看起来像矫枉过正一点给我。我将烯nicen易变的方法:

class RetVal:
 def __init__(self):
   self.result = None


def threadfunc(retVal):
  retVal.result = "your return value"

retVal = RetVal()
thread = Thread(target = threadfunc, args = (retVal))

thread.start()
thread.join()
print(retVal.result)
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top