2010-08-22 33 views
10

Nếu không đạt mức tối đa trong khi vẫn còn hiệu quả?có giới hạn số lượng chuỗi có thể chạy cùng một lúc không?

Tôi đang tạo 14 chuỗi, mỗi chuỗi sẽ mở danh sách URL (khoảng 500) tạo chuỗi mới cho mỗi chuỗi, sau đó tải xuống và thêm nó vào db của MySQL. Kích thước nhóm MySQL được đặt thành 50.

Đây là tác vụ cào trong RoR.

Điều này có hoạt động tốt hơn khi sử dụng Kernal#fork hoặc một số phương pháp khác không?

+3

bạn có thể 'làm hỏng' một số ít! ;) –

+0

khắc phục điều đó, cảm ơn! không đọc tiêu đề: O – loosecannon

Trả lời

2

Vâng, vì các chủ đề của bạn sẽ bị ràng buộc IO, tin tốt là cả hai chủ đề Ruby 1.8 và 1.9 sẽ hoạt động cho điều này. Ruby 1.8 sử dụng "các luồng không gian người dùng", nghĩa là không có chủ đề hệ điều hành mới thực sự nào được tạo ra khi bạn tạo các luồng mới trong Ruby. Điều này là xấu cho đa nhiệm CPU, vì chỉ có một chuỗi Ruby thực sự chạy cùng một lúc, nhưng tốt cho việc đa nhiệm IO. Ruby 1.9 sử dụng các chủ đề thực sự và sẽ tốt cho cả hai.

Số lượng chuỗi bạn có thể tạo thực sự tùy thuộc vào hệ thống của bạn. Tất nhiên là có giới hạn thực tế, nhưng có lẽ bạn không muốn đến bất cứ đâu gần họ. Đầu tiên, trừ khi các máy chủ bạn đang downloaidng từ rất chậm và kết nối của bạn là rất nhanh, chỉ cần một vài chủ đề sẽ làm ướt kết nối Internet của bạn. Ngoài ra, nếu bạn đang lấy rất nhiều trang từ một máy chủ duy nhất, việc đưa 500 yêu cầu vào cùng một lúc từ 500 luồng cũng sẽ không thực hiện được gì.

Tôi bắt đầu khá nhỏ: 10 hoặc 20 chuỗi chạy cùng một lúc. Tăng hoặc giảm tùy thuộc vào tải máy chủ, băng thông của bạn, v.v. Ngoài ra còn có vấn đề kết nối đồng thời với cơ sở dữ liệu MySQL. Tùy thuộc vào cách các bảng của bạn được thiết lập và mức độ lớn của chúng, việc cố gắng chèn quá nhiều dữ liệu cùng một lúc sẽ không hoạt động tốt.

+0

tôi đã kết thúc việc bỏ luồng và thêm chỉ mục vào cơ sở dữ liệu để kiểm tra bản sao 1000x nhanh hơn vì vậy tôi không còn cần tăng tốc, và như bạn đã nói nó chỉ tải kết nối của tôi. Cảm ơn! – loosecannon

3

Với Ruby 1.8, điều này thực tế bị giới hạn về số lượng bộ nhớ bạn có. Bạn có thể tạo hàng chục nghìn luồng cho mỗi quy trình. Trình thông dịch Ruby xử lý việc quản lý các luồng và chỉ một hoặc hai luồng gốc được tạo ra. Nó không thực sự đa nhiệm khi CPU chuyển đổi giữa các luồng.

Ruby 1.9 sử dụng chuỗi gốc. Giới hạn dường như là những gì được hệ điều hành cho phép. Chỉ để thử nghiệm, tôi có thể tạo hơn 2000 luồng trên mac của mình với Ruby 1.9 trước khi hệ điều hành không cho phép nữa.

Lưu ý rằng có hàng nghìn luồng cho một quy trình không phải là một ý tưởng hay. Lập kế hoạch chủ đề trở thành một gánh nặng lâu trước đó.

+0

ok cảm ơn! có thể bị bệnh chỉ cần sử dụng những người đầu tiên 14, và không phải tất cả các tiểu chủ đề. Cảm ơn! – loosecannon

+0

bạn có nghĩa là thực tế không giới hạn? (và có, có thêm chủ đề làm cho ứng dụng của bạn runnn ... chậm hơn ... trên 1.8.6 vì các ref được chia sẻ cho GC, mặc dù tôi cho rằng bạn có thể sử dụng REE để tránh những). – rogerdpack

+0

Không, chắc chắn không giới hạn. Tôi chắc rằng bạn đồng ý rằng nó "bị hạn chế trong thực tế" bởi số lượng RAM có sẵn. – Alkaline

9
require 'open-uri' 
a = 'http://www.example.com ' * 30 
arr = a.split(' ') 

arr.each_slice(3) do |group| 
    group.map do |site| 
    Thread.new do 
     open(site) 
     p 'finished' 
    end 
    end.each(&:join) 
end 
+0

ví dụ điển hình. +1 từ tôi. – Rubyrider

+0

Tôi thực sự thích việc có thể tạo chuỗi chủ đề bằng cách sử dụng each_slice. Không bao giờ sử dụng each_slice trước đây, vì vậy đây là một giải pháp rất khai sáng –

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