2010-11-09 22 views
6
import threading 
import Queue 
import urllib2 
import time 

class ThreadURL(threading.Thread): 

    def __init__(self, queue): 
     threading.Thread.__init__(self) 

     self.queue = queue 

    def run(self): 
     while True: 
      host = self.queue.get() 
      sock = urllib2.urlopen(host) 
      data = sock.read() 

      self.queue.task_done() 

hosts = ['http://www.google.com', 'http://www.yahoo.com', 'http://www.facebook.com', 'http://stackoverflow.com'] 
start = time.time() 

def main(): 
    queue = Queue.Queue() 

    for i in range(len(hosts)): 
     t = ThreadURL(queue) 
     t.start() 

    for host in hosts: 
     queue.put(host) 

    queue.join() 

if __name__ == '__main__': 
    main() 
    print 'Elapsed time: {0}'.format(time.time() - start) 

Tôi đã cố gắng tìm hiểu cách thực hiện Threading và sau một vài hướng dẫn, tôi đã đưa ra phần trên.Cần một số trợ giúp với việc phân luồng/xếp hàng Python

gì nó là nghĩa vụ phải làm là:

  1. Initialiase hàng đợi
  2. Tạo hồ bơi Chủ đề của tôi và sau đó xếp hàng lên danh sách các host
  3. lớp ThreadURL của tôi sau đó nên bắt đầu công việc một lần một host là trong hàng đợi và đọc dữ liệu trang web
  4. Chương trình sẽ hoàn thành

Điều tôi muốn biết trước hết là, m tôi làm điều này một cách chính xác? Đây có phải là cách tốt nhất để xử lý các chủ đề không?

Thứ hai, chương trình của tôi không thể thoát. Nó in ra dòng Elapsed time và sau đó treo ở đó. Tôi phải giết thiết bị đầu cuối của tôi để nó biến mất. Tôi giả định điều này là do việc sử dụng sai số queue.join() của tôi?

Trả lời

6

Mã của bạn trông ổn và khá sạch sẽ.

Lý do ứng dụng của bạn vẫn "treo" là các chuỗi công nhân vẫn đang chạy, chờ ứng dụng chính đưa thứ gì đó vào hàng đợi, mặc dù chủ đề chính của bạn đã hoàn tất.

Cách đơn giản nhất để khắc phục điều này là đánh dấu chủ đề là daemon, bằng cách thực hiện t.daemon = True trước khi cuộc gọi của bạn bắt đầu. Bằng cách này, các chủ đề sẽ không chặn chương trình dừng lại.

2

có vẻ ổn. yann đúng về đề xuất daemon. điều đó sẽ khắc phục sự cố của bạn. câu hỏi duy nhất của tôi là tại sao lại sử dụng hàng đợi? bạn không thực hiện bất kỳ giao tiếp luồng chéo nào, vì vậy có vẻ như bạn chỉ có thể gửi thông tin máy chủ như là một arg tới ThreadURL init() và thả hàng đợi.

không có gì sai với nó, chỉ cần tự hỏi.

+0

Tôi đã sử dụng Hàng đợi vì đó là những gì hầu hết các ví dụ/hướng dẫn tôi đọc đang sử dụng. Tại sao hàng đợi chỉ hữu ích khi gửi dữ liệu giữa các luồng? Các thông tin duy nhất tôi có thể tìm thấy trên luồng/xếp hàng là hướng dẫn (trong đó cho thấy mã và không phải là rất nhiều thông tin) và các tài liệu chính thức mà quá phức tạp tôi, một người mới bắt đầu luồng, để hiểu. – dave

+1

nếu bạn chỉ đang khởi chạy một luồng cho mỗi máy chủ, bạn có thể bỏ qua hàng đợi và chuyển một máy chủ duy nhất đến __init __(). nhưng hãy xem xét trường hợp bạn có một danh sách lớn các máy chủ lưu trữ mà bạn muốn cấp cho một số chuỗi có giới hạn. bạn sẽ sử dụng hàng đợi để phân phối công việc. –

1

Một điều, trong chức năng chạy chuỗi, trong khi vòng lặp True, nếu một số ngoại lệ xảy ra, task_done() có thể không được gọi tuy nhiên get() đã được gọi. Vì vậy, queue.join() có thể không bao giờ kết thúc.

Các vấn đề liên quan