문제

스레드를 어떻게 튜플 또는 내 선택의 값을 파이썬에서 부모에게 돌려 보내려면 어떻게해야합니까?

도움이 되었습니까?

해결책

인스턴스화 할 것을 제안합니다 대기열 스레드를 시작하고 스레드의 Args 중 하나로 전달하기 전에 : 스레드가 끝나기 전에 .put큐의 결과는 인수로받은 결과입니다. 부모는 할 수 있습니다 .get 또는 .get_nowait 마음 의지.

대기열은 일반적으로 파이썬에서 스레드 동기화 및 통신을 배열하는 가장 좋은 방법입니다. 본질적으로 스레드 안전, 메시지 통과 차량-일반적으로 멀티 태스킹을 구성하는 가장 좋은 방법!-)

다른 팁

스레드가 완료 될 때까지 join ()을 호출하는 경우 결과를 스레드 인스턴스 자체에 첨부 한 다음 join ()가 반환 한 후 기본 스레드에서 검색 할 수 있습니다.

반면에, 당신은 스레드가 완료되었고 결과를 사용할 수 있음을 발견하려는 방법을 알려주지 않습니다. 이미 그렇게 할 수있는 방법이 있다면, 아마도 결과를 얻는 가장 좋은 방법을 당신과 우리에게 말할 것입니다.

큐 인스턴스를 매개 변수로 전달해야합니다. 그러면 .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로 데이터베이스에서 사용자 Infos를 확인해야한다고 생각합니다.

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

파이썬 스레딩 모듈에는 잠금과 관련된 조건 객체가 있습니다. 하나의 방법 acquire() 기본 방법에서 반환되는 모든 값을 반환합니다. 자세한 내용은: 파이썬 조건 객체

jcomeau_ictx의 제안을 기반으로합니다. 내가 가장 간단한 것. 여기서 요구 사항은 서버에서 실행되는 세 가지 프로세스에서 종료 상태 Staus를 얻고 세 가지 모두가 성공하면 다른 스크립트를 트리거하는 것이 었습니다. 이것은 잘 작동하는 것 같습니다

  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() 리턴 값을 제공합니다.

쉬운 프로그램의 경우 위의 답변은 나에게 과도하게 보인다. 나는 돌연변이 가능한 접근법을 나타냅니다.

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