Phiên xử lý luồng awe

Khái quát về threading trong Ruby

Làm việc đa nhiệm không phải là một chuyện dễ dàng nhưng lại thường là một phần thiết yếu trong cuộc sống của mỗi chúng ta. Khi bận, chúng ta thường sẽ phải tìm cách hoàn thành nhiều việc trong cùng một khoảng thời gian. Tuy nhiên, làm việc đa nhiệm quá nhiều cũng dễ dàng khiến chúng ta mất tập trung và gây ra những sai lầm.

Phiên xử lý luồng awe
)

May mắn thay là sẽ không có mối nguy hiểm nào cả. Cho đến nay, chúng ta vẫn chưa rõ chính xác ý nghĩa của “cùng một lúc” trong Thread của Ruby. Trong lập trình, thường có rất nhiều sự nhầm lẫn giữa Parallelism (song song) và Concurrency (đồng thời). Parallelism liên quan đến việc sử dụng một CPU đa lõi để thực hiện nhiều tác vụ cùng một lúc theo đúng nghĩa đen (các CPU đơn lõi trông có vẻ như đang làm nhiều việc cùng một lúc, nhưng bản chất chúng vẫn phải thực hiện từng việc một). Mặt khác, Concurrency liên quan đến việc một CPU duy nhất xử lý một số tác vụ, chuyển đổi giữa tác vụ này tác vụ kia cho đến khi tất cả đã hoàn thành.

Nếu bạn đang nấu một bữa ăn theo cách tuần tự (không phải đồng thời hoặc song song), bạn sẽ phải thực hiện từng bước riêng lẻ và hoàn chỉnh. Điều này có nghĩa là, khi bạn đặt nước sôi, bạn sẽ không thể làm gì khác ngoài việc chờ đợi nước sôi. Tuy nhiên, nếu bạn làm theo cách "concurrency", bạn có thể để nồi nước đó và bắt đầu thái rau. Cuối cùng, nếu bạn làm theo cách "parallelism, bạn sẽ có một đầu bếp khác hỗ trợ bạn, (mặc dù sẽ tốn diện tích trong nhà bếp hơn và gặp rủi ro cao hơn do các vấn đề về giao tiếp).

Vậy thì Ruby xử lý vấn đề đa nhiệm như thế nào? Thực ra thì vấn đề này thực sự là một vấn đề khá là nhức nhối đối với Ruby. Các trình thông dịch Ruby tiêu chuẩn (MRI và YARV) không sử dụng "parallelism". Hơn nữa, về mặt kỹ thuật, các luồng cho phép "concurrency", nhưng nó chỉ theo một cách khá hạn chế. MRI và YARV sử dụng Global Interpreter Lock (GIL), có nghĩa là chỉ một luồng có thể được thực thi trong trình thông dịch tại bất kỳ thời điểm nào. Vì vậy, ngay cả trên một máy tính đa lõi, "parallelism" là không thể.

Ở đầu bài viết, chúng ta đã thấy cách mười thread có thể thực hiện một tác vụ “cùng một lúc”. Thực ra thì, đã có một sự ngây thơ vô (số) tội ở đây. Tác vụ chậm mà các method đó xử lý chỉ đơn giản là sleep một giây và sau đó puts ra. Tác vụ này, giống như đợi nồi nước sôi, có thể được hưởng lợi đáng kể từ "Concurrency". Nếu chúng ta thay thế tác vụ đó bằng một phép tính toán phức tạp thì kết quả sẽ chẳng có sự chênh lệch gì đáng kể cả.

Điều này không có nghĩa rằng Threads không có tác dụng gì. Cũng giống như slow_method có sleep trong ví dụ ở đâu bài viết, các quy trình khác mà có sự gián đoạn trong việc thực thi thì áp dụng "concurrency" sẽ cải thiện tốc độ lên rất nhiều. Mà thông thường thì bất kỳ thứ gì liên quan đến input - dù từ người dùng hoặc server đều có những sự gián đoạn như vậy. Nếu không phân luồng thì chương trình của chúng ta sẽ phải tạm dừng cho đến khi nhận được đầu vào. Và Threads của Ruby hoàn toàn có thể giải quyết tốt sự thiếu hiệu quả này.

Nếu việc Ruby không "thực sự" đa nhiệm khiến bạn thất vọng thì bạn có thể cân nhắc chuyển trình thông dịch của mình sang thứ gì đó như JRuby (sử dụng Java Virtual Machine và cho phép chạy "parallelism". Nếu không, hãy sử dụng threading để tăng hiệu suất chương trình của bạn (cố gắng chú ý đừng để xảy ra lỗi nào quá dị nhé

Phiên xử lý luồng awe
).


source: https://medium.com/@micksheridan.24/unravelling-ruby-threads-2798f2c46e45