18

Tôi đã từng hack với Ruby theo thời gian, nhưng tôi đã không làm bất cứ điều gì lớn hoặc đa luồng với nó. Tôi đã nghe nói rằng MRI chỉ hỗ trợ chủ đề màu xanh lá cây và JRuby hỗ trợ chủ đề bản địa thông qua JVM. Tuy nhiên, tôi vấp ngã khi nhận xét trên blog và các nhóm thảo luận nói rằng "Rails không phải là chủ đề an toàn" hoặc bản thân Ruby không phải là chủ đề an toàn. Ví dụ, ai đó đã nhận xét rằng có sự cố với câu lệnh yêu cầu. Nghe có vẻ hơi cơ bản.Ruby/Rails an toàn chủ đề

Tôi đã thấy nhiều ứng dụng Java không xử lý đồng thời đúng cách và đôi khi tôi gặp ác mộng về chúng :-) Nhưng ít nhất bạn có thể viết các ứng dụng an toàn trong Java nếu bạn thực sự biết bạn đang làm gì (nó không dễ dàng).

Tất cả điều này nghe khá đáng báo động, ai đó có thể giải thích thêm - vấn đề chính xác là gì và Rails quản lý hoạt động như thế nào nếu đây là trường hợp? Tôi có thể viết mã Ruby đa luồng hoạt động chính xác mà không có điều kiện chủng tộc và deadlocks không? Là nó di động giữa JRuby và MRI hay tôi phải hack trong mã JVM cụ thể để tận dụng lợi thế của các chủ đề bản địa JVM đúng cách?

EDIT:

tôi nên đã hỏi hai câu hỏi, bởi vì mọi người dường như chỉ để trả lời các đường ray luồng thứ (đó là tốt đẹp trong chính nó) và luồng xanh vs luồng bản địa. Mối quan tâm của tôi về các vấn đề cốt lõi của Ruby về chủ đề an toàn chưa thực sự được giải quyết. Dường như có ít nhất một (chưa được giải quyết?) issue với yêu cầu trong một số trường hợp nhất định.

+0

Trùng lặp: http://stackoverflow.com/questions/129226/what-are-the-current-state-of-affairs-on-threading-concurrency-and-forked-proces/129331#129331 –

Trả lời

5

Giải pháp thông thường cho MRI là chạy nhiều phiên bản Rails, mỗi yêu cầu xử lý độc lập. Vì MRI không đa luồng dù sao, bạn không thể chạy nhiều phiên bản Rails trên đầu trang của nó. Điều này có nghĩa là bạn có một lần truy cập bộ nhớ vì Rails được nạp một lần cho mỗi quá trình Ruby.

Vì JRuby hỗ trợ các chuỗi gốc, bạn luôn có thể chạy một số phiên bản Rails trong một JVM đơn lẻ. Nhưng với Rails được an toàn thread, bạn có thể cắt nó xuống một, có nghĩa là sử dụng bộ nhớ thấp hơn và ít biên dịch JIT.

Charles Nutter (JRuby) có nice summary.

+0

Cảm ơn, Charles Bản tóm tắt của Nutter thật tuyệt vời. – auramo

1

Tôi nghĩ rằng các áp phích trước đây đã bao gồm các trường hợp của Rails khá tốt, vì vậy tôi sẽ không bận tâm đến những thứ đó.

Chắc chắn là có thể viết các ứng dụng Ruby được tạo chuỗi. Một số vấn đề tồn tại với các chuỗi ruby ​​là chúng có màu xanh lục khi chúng được quản lý bởi máy ảo. Hiện tại, trình thông dịch mặc định (MRI) chỉ có một luồng hệ thống thực sự cần được chia sẻ bởi tất cả các chủ đề mà trình thông dịch đã kiểm soát.

Nhược điểm của điều này là nếu bạn có một máy tính có nhiều bộ xử lý hoặc lõi, bạn không thể có một luồng trong ứng dụng đang chạy trên một số lõi khác. Đây là một thỏa thuận khá lớn đối với những người đang chạy máy chủ và các ứng dụng hiệu suất cao.

Đối với câu hỏi về mã thông dịch cụ thể của bạn: Tôi không nghĩ vậy. AFAIK bạn không phải làm bất cứ điều gì đặc biệt để chăm sóc các chủ đề JRuby/JVM.

Ngoài ra: This article trên Igvita để có cái nhìn tốt về trạng thái đồng thời trong Ruby.

14

Đầu tiên và trước hết, Ruby 1.9 (bản phát hành chính thức gần đây nhất) now uses native (kernel) threads. Các phiên bản trước của Ruby đã sử dụng các chuỗi màu xanh lục. Để trả lời câu hỏi của bạn một cách ngắn gọn, trước 1.9, các chủ đề thường không được sử dụng trong các ứng dụng Ruby lớn hay nhỏ một cách chính xác bởi vì chúng không đặc biệt an toàn hoặc đáng tin cậy.

Điều này không đặc biệt đáng báo động vì trước phiên bản 2.2 Đường ray không cố gắng tạo luồng, vì vậy chúng tôi thường xử lý xử lý không đồng bộ thông qua việc sử dụng nhiều quy trình, khóa ghi cơ sở dữ liệu và hàng đợi thư như Starling. Đây thường là một cách khá đáng tin cậy để mở rộng ứng dụng web - ít nhất là đáng tin cậy hơn các ứng dụng Java đa luồng không chính xác - và có thêm lợi thế là dễ dàng mở rộng ứng dụng của bạn sang nhiều bộ xử lý và máy chủ.

Tôi không biết liệu vấn đề 'yêu cầu' mà bạn đã đề cập đã được giải quyết là 1.9 chưa, nhưng tôi liên tưởng một cách khiêm nhường rằng nếu bạn yêu cầu thư viện động trong chuỗi mới thì bạn có nhiều vấn đề về bảo trì.

Nếu bạn muốn tránh hoàn toàn chủ đề, Ruby 1.9 also supports fibers, sử dụng phương pháp chia sẻ không có gì để đồng thời và, từ những gì tôi thu thập, thường dễ viết và duy trì hơn chủ đề. Performance numbers here.

+0

Tại sao lại hữu ích khi so sánh * mọi thứ * với "* không chính xác * các ứng dụng Java đa luồng"? –

+0

@KirkWoll Đọc của tôi là người trả lời ngụ ý rằng "khi luồng là nguy hiểm trong một ngôn ngữ, nó có thể không có giá trị trong ngôn ngữ đó." – Jackson