Lua Cothread
Gần đây mình đã thử chơi với ngôn ngữ Go và rất thích mô hình lập trình goroutine, đặc biệt là việc dùng chan để giao tiếp giữa các thread rất tiện lợi. Trong một buổi chiều hôm nay, mình đã viết một thư viện nhỏ cho Lua nhằm mô phỏng kiểu lập trình này và tạm đặt tên là lua cothread. Thư viện này được xây dựng dựa trên coroutine có sẵn của Lua, mình chỉ việc viết thêm một bộ điều phối (scheduler) đơn giản.
Thư viện hiện tại cung cấp những API sau:
cothread.run(f, …)
Khởi động một hàm f
và đưa nó vào trong bộ điều phối. Các tham số ...
sẽ được truyền vào hàm f
. Chức năng này tương tự như từ khóa go
trong Go.
cothread.resume()
Thực hiện một lượt chạy (tick). Khác với mô hình đa luồng của Go, thư viện này hoạt động theo từng tick riêng lẻ. Điều này rất phù hợp để tích hợp vào các framework khác. Mỗi khi framework gọi hàm resume
, tất cả các thread được bộ điều phối quản lý sẽ thực hiện một tick. Hàm này sẽ trả về số lượng thread đang hoạt động tại thời điểm gọi.
cothread.sleep(ti)
Cho thread hiện tại nghỉ ngơi trong ti
tick. Lưu ý rằng giá trị ti
có thể là 0, điều này có thể khiến hàm resume
chạy liên tục không dừng.
cothread.chan()
Tạo một kênh truyền tin (message channel) tương tự như Go. Tuy nhiên, phiên bản này chỉ hỗ trợ chế độ blocking đơn giản. Khi ghi dữ liệu vào channel, thread sẽ bị chặn lại cho đến khi có một thread khác đọc dữ liệu từ kênh này hoặc kênh bị đóng lại. Tương tự như vậy cho thao tác đọc dữ liệu.
chan:read()
Đọc một dữ liệu từ channel theo kiểu blocking. Nếu channel bị đóng, hàm sẽ trả về nil
.
chan:write()
Ghi một dữ liệu vào channel theo kiểu blocking và trả về true
. Nếu channel đã bị đóng, hàm sẽ trả về nil
.
cothread.select(tbl)
Giống với select
trong Go. Bạn có thể truyền vào một bảng chứa nhiều channel. Khi bất kỳ channel nào trong bảng có dữ liệu để đọc, nhánh tương ứng sẽ được thực thi. Bảng này cũng có thể chứa một mục default
để xử lý khi không có channel nào sẵn sàng. Nếu không có mục default
, select
sẽ chờ blocking cho tới khi có dữ liệu từ một channel nào đó. Cách dùng cụ thể vui lòng xem trong ví dụ.
Bạn có thể tham khảo mã nguồn và ví dụ tại đây.