2010-11-01 46 views
14

Tôi có một chuỗi mở rộng Thread. Mã trông giống như thế này;Python - kiểm tra trên một sợi/xóa khỏi danh sách

class MyThread(Thread): 
    def run(self): 
     # Do stuff 

my_threads = [] 
while has_jobs() and len(my_threads) < 5: 
    new_thread = MyThread(next_job_details()) 
    new_thread.run() 
    my_threads.append(new_thread) 

for my_thread in my_threads 
    my_thread.join() 
    # Do stuff 

Vì vậy, đây trong mã giả của tôi, tôi kiểm tra để xem nếu có bất kỳ công việc (như một db vv) và nếu có một số công ăn việc làm, và nếu có ít hơn 5 chủ đề hoạt động, tạo chủ đề mới. Vì vậy, từ đây, tôi kiểm tra chủ đề của tôi và đây là nơi tôi gặp khó khăn, tôi có thể sử dụng .join() nhưng sự hiểu biết của tôi là - điều này sau đó đợi cho đến khi nó kết thúc nếu chuỗi đầu tiên nó kiểm tra trong tiến trình, sau đó nó chờ cho đến khi nó được thực hiện - ngay cả khi các chủ đề khác được hoàn thành ....

vì vậy có cách nào để kiểm tra xem một luồng có được thực hiện hay không, sau đó loại bỏ nó?

ví dụ

for my_thread in my_threads: 
    if my_thread.done(): 
     # process results 
     del (my_threads[my_thread]) ?? will that work... 

Trả lời

24

Như TokenMacGuy nói, bạn nên sử dụng thread.isAlive() để kiểm tra xem a thread vẫn chạy. Để loại bỏ đề không còn chạy ra khỏi danh sách của bạn, bạn có thể sử dụng một list comprehension:

for t in my_threads: 
    if not t.isAlive(): 
     # get results from thtead 
     t.handled = True 
my_threads = [t for t in my_threads if not t.handled] 

Điều này tránh được vấn đề loại bỏ các mục từ danh sách trong khi iterating trên nó.

+0

Cảm ơn, nhưng điều đó có nghĩa là kết quả có thể bị mất? Nếu một chủ đề không còn tồn tại nữa thì tôi cần có kết quả. – Wizzard

+0

Đúng vậy. Tôi đã sửa đổi câu trả lời của mình để tính đến điều này. – Arlaharen

+5

'is_alive()' trong Python 2.6+ – trim

4

Better cách là sử dụng Queue lớp: http://docs.python.org/library/queue.html

Nhìn vào đoạn code ví dụ điển hình ở dưới cùng của trang tài liệu:

def worker(): 
    while True: 
     item = q.get() 
     do_work(item) 
     q.task_done() 

q = Queue() 
for i in range(num_worker_threads): 
    t = Thread(target=worker) 
    t.daemon = True 
    t.start() 

for item in source(): 
    q.put(item) 

q.join()  # block until all tasks are done 
+1

Cảm ơn, nhưng tôi có thể gặp vấn đề tương tự với q.join() không? nếu tôi có 20 công việc cần làm nhưng chỉ muốn chạy tối đa 4 công việc tại một thời điểm. Nếu 3 được thực hiện và một không được thực hiện sau đó tôi không muốn làm chậm chương trình trong khi nó chờ đợi cho kết quả 1 ... – Wizzard

0

Câu trả lời đã được bảo hiểm, nhưng vì đơn giản ...

# To filter out finished threads 
threads = [t for t in threads if t.is_alive()] 

# Same thing but for QThreads (if you are using PyQt) 
threads = [t for t in threads if t.isRunning()] 
Các vấn đề liên quan