Seçimi geri almak için bir parçacığı veya herhangi bir değeri Python'daki ana öğeye geri nasıl gönderirim?İş parçacığından döndürülen değeri döndürür
cevap
Sana parçacığı başlamadan önce Queue.Queue örneğini ve parçacığının args biri olarak geçmesi öneririm. Ebeveyn, istediği zaman .get
veya .get_nowait
yapabilir.
Kuyruklar genellikle Python iplik senkronizasyonu ve iletişimi düzenlemek için en iyi yoldur: bunlar özünde evreli, ileti geçirme araçları konum - genel olarak çoklu görev düzenlemenin en iyi yolu -)
Python iş parçacığı modülünde, kilitlerle ilişkili durum nesneleri vardır. Bir yöntem acquire()
, temel alınan yöntemden hangi değer döndürülürse döndürülür. Daha fazla bilgi için: bir argüman olarak alınan sıraya iplik bitmeden, bu .put
s sonucu: Python Condition Objects
başka bir yaklaşım! iş parçacığına bir geriçağırım işlevini iletmektir. Bu, her zaman yeni iş parçacığından, üst öğeye değer döndürmek için basit, güvenli ve esnek bir yol sağlar.
# 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()
Buradaki sorun, geri arama hala çalışır Orijinal iş parçacığı yerine çocuk iş parçacığı. – babbageclunk
@wilberforce, hangi sorunlara neden olabileceğini açıklayabilir misiniz? –
Tamam. Geri arama, iş parçacığı çalışırken üst iş parçacığının da yazdığı bir günlük dosyasına yazıyorsa bu örnek olur. Geri arama, çocuk iş parçacığı içinde çalıştığı için, aynı anda gerçekleşen ve çarpışan iki yazma riski vardır. Bozuk ya da araya sokulmuş çıktının alınması ya da günlüğe kaydetme çerçevesinin bazı dahili defter tutma işlemleri yapması durumunda bir çarpışma olabilir. Bir iş parçacığı güvenli kuyruğu kullanmak ve bir iş parçacığına sahip olmak tüm yazıyı bunu engeller. Bu tür problemler, deterministik olmadıkları için çirkin olabilirler - sadece üretimde ortaya çıkabilirler ve çoğaltılamazlar. – babbageclunk
tamamlamak iplik beklemek() katılmak çağırarak olsaydı, sadece Konu örneğine kendisine sonucunu eklemenizi ve daha sonra katılmak() döndükten sonra ana iş parçacığı çağırın.
Diğer taraftan, iş parçacığının yapıldığını ve sonucun kullanılabilir olduğunu nasıl anlamaya niyetlendiğinizi bize söylemezsiniz. Eğer bunu zaten yapmanın bir yolu varsa, muhtemelen (ve eğer bize söyleseydiniz) sonuçları elde etmenin en iyi yoluna işaret edecektir.
* sonucu yalnızca Thread örneğinin kendisine ekleyebilirsiniz. Thread ismini, hedefin bu örnekle ilişkilendirebilmesi için, çalıştığı hedefe nasıl geçirirsiniz? –
Piotr Dobrogost, eğer alt sınıfın alt sınıfını oluşturmuyorsanız, örneğiniz için iş parçacığı sonuna kadar threading.current_thread() öğesini kullanabilirsiniz. Ben buna çirkin denirdim, ama Alex'in yaklaşımı her zaman daha zarifti. Bu, bazı durumlarda sadece daha uygun. –
Eğer join() 'sadece çağrılan yöntem geri dönüşünü döndürürse ... güzel olur, bunun yerine" Yok "u döndürür. – ArtOfWarfare
Bir Kuyruk örneğini parametre olarak iletmeniz gerekir, ardından döndürme nesnesini sıraya sığdırmalısınız. Verdiğiniz değeri, queue.get() ile gönderebilirsiniz.
Örnek: birden çok iş parçacığı için
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)
Kullanım:
#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()
bu uygulamayı kullanır ve bu benim için iyi çalışıyor. Keşke yapmanı diliyorum.
Thread_.start() 'ı kaçırmıyor musunuz?Tabii – sadmicrowave
Ben sadece burada çizgiyi koymak kaçırmak iplik başlamak :) haber için teşekkürler. –
Birden fazla iş parçacığınız varsa nasıl görünürdü? que.get() sadece benim için bir iş parçacığının sonucunu döndürür? – ABros
Kullanım lambda hedef iplik fonksiyonunu sarın ve bir kuyruğunu kullanarak ana konuya geri dönüş değerini geçmesi. (Orijinal hedef fonksiyonu ekstra kuyruk parametresi olmadan değişmez.)
örnek kod:
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())
Çıktı:
4
POC: Sen queue senkronize kullanabilirsiniz
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
modülü.
def check_infos(user_id, queue):
result = send_data(user_id)
queue.put(result)
Şimdi böyle verilerinizi alabilirsiniz:
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()
Sürpriz kimse bunu sen tekini söz olduğum
Eğer bilinen bir kimliğe sahip veritabanından bir kullanıcı bilgilerinizi kontrol gerekir düşünün Belki de bunun habersiz olduğum başlıca sorunları vardır.
Bu mükemmel çalışıyor! Varsa, bu yaklaşımla eksik olan şeyler hakkında bazı fikirleri duymak isterim. –
çalışır. Sadece var olan bir işlevi - ve bu çok kafa karıştırıcı şeyleri (okunabilirlik) - uzmanlaşmak çirkin - 1. cevap hakkındaki yorumu görün. – kxr
Çok iş parçacığına ne dersin? – backslash112
Aşağıdaki sarma işlevi, varolan bir işlevi saracak ve her ikisini de işaret eden bir nesneyi döndürecektir (böylece start()
, join()
, vb .'yi arayabilmeniz için) ve aynı zamanda nihai dönüş değerini görüntüleme/görüntüleme.
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
Tamam görünüyor ve threading.Thread
sınıf kolayca işlevselliği bu tür (*) uzatılabilir görünüyor, bu yüzden zaten orada değil neden merak ediyorum. Yukarıdaki yöntemle bir kusur var mı?
(*) Bu soru için husanu'nun cevabının tam olarak threading.Thread
alt sınıfını, join()
döndürme değerini verdiği bir sürümle sonuçlandığını unutmayın.
jcomeau_ictx'ın önerisine dayanmaktadır. Karşılaştığım en basit olanı. Buradaki gereksinim, sunucuda çalışan üç farklı işlemden çıkış durumu statüsünü almak ve üçünün de başarılı olması durumunda başka bir komut dosyasını tetiklemekti. Bu
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
- 1. OpenGL'yi Android'deki ana iş parçacığından kullanma
- 2. ViewModel özelliklerine ayrı iş parçacığından erişme
- 3. Arka plan iş parçacığından sunucuya eşzamanlı istek
- 4. CUDA'daki ayrılma - Çekirdekdeki bir iş parçacığından çıkış
- 5. g_hash_table_contains beklenmeyen değeri döndürür
- 6. NDK C++ iş parçacığından Java API nasıl aranır?
- 7. Process.WorkingSet64, maksimum değeri 4294967295 döndürür
- 8. mysqli_statement :: num_rows() yanlış değeri döndürür
- 9. Başka bir iş parçacığından dönen nesneler mi alıyorsunuz?
- 10. WPF C# - Başka bir iş parçacığından liste kutusu düzenleme
- 11. Arka plan iş parçacığından bir databoundview veri kümesini doğru güncelleştirin
- 12. WPF Uygulamasını UI olmayan iş parçacığından yeniden başlat
- 13. Delphi'deki ana iş parçacığından bir TThread'e nasıl mesaj gönderilir?
- 14. İstemcinin iş parçacığından (threading, python) sunucunun değişkenini değiştirin
- 15. Çekirdek iş parçacığından dönersek kthread_stop kullanmak zorunlu mudur?
- 16. Realm.io - Hata düzeltildi! Yanlış iş parçacığından erişilen bölge
- 17. OpenGL ES işlevleri neden başka bir iş parçacığından çağrılabilir?
- 18. API'si, JSON'u döndürür ancak HTML istisnaları, HTML'de döndürülen JSON istemcisi
- 19. CIPerspectiveCorrection filtresi döndürülen görüntüyü döndürür ve ters çevrilmiş
- 20. jQuery döndürülen değeri bir dizi gibi gösterir mi?
- 21. Ana UI iş parçacığındaki lambda/std :: işlevinin çağrılması bir arka plan iş parçacığından çağrılıyor
- 22. Python/Urllib2/Threading: Birden çok indirme iş parçacığından daha hızlı tek indirme iş parçacığı. Niye ya?
- 23. Dönüşüm operatörü bir değeri nasıl döndürür?
- 24. döndürülen jsondaki çift tırnak
- 25. SQL'de döndürülen satırlar nasıl numaralandırılır?
- 26. Çoklu iş parçacığı sorunu değeri güncelleştiriliyor
- 27. SoapClient "NULL" döndürür, ancak __getLastResponse() XML döndürür
- 28. Bir iş, işini bitirdikten sonra nasıl bir değer döndürür?
- 29. Perl'de döndürülen dizine doğrudan dizinleme
- 30. dış genişlik ve genişlik, firefox'taki yanlış değeri döndürür.
'iplik bitmeden, bunu ne piton tarafından otomatik olarak yapılacaktır anlamına bir argument' olarak alınan sıraya sonucu .puts iyi çalışıyor gibi görünüyor? eğer değilse (tasarım ipucu olarak anılırsa) cevabın netleşmesini sağlayabilirsiniz. – n611x007
Bunun için mevcut bir işlevi uzmanlaşmak çirkin; Kuyrukta, tek bir sonuç sorunu için gereksiz bir ek yük vardır. Daha açık ve etkin bir şekilde alt sınıf "threading.Thread" ve yeni run() yöntemi, sonucu "self.ret = ..." gibi öznitelik olarak kaydeder (Çok daha rahat bir şekilde, dönüş değerlerini/istisnalarını işleyen bir İş Parçasının alt sınıfı olur. Özel hedef işlevi.Gelişmiş "threading.Thread" kutusundan dışarı sunmak için uzatılmalıdır - eski davranış ile uyumlu olurdu "dönüş Yok".) – kxr