无标题 - nói dối e blog

无标题

Thư viện coroutine của C

Thư viện coroutine của C

Tôi vừa hoàn thành việc xây dựng một thư viện coroutine cho ngôn ngữ C. Đây là dự án mà tôi tin rằng đã có hàng ngàn lập trình viên C từng thực hiện, nhưng khi tìm kiếm trên Google, tôi thấy các giải pháp hiện có hoặc có giao diện không như mong muốn, hoặc tiêu tốn quá nhiều tài nguyên hệ thống.

Về mặt kỹ thuật, trên nền tảng Windows, chúng ta có thể sử dụng công nghệ Fiber để xây dựng coroutine, còn trên các hệ thống Posix thì có giải pháp setcontext tiện lợi hơn nhiều. Yêu cầu cốt lõi của tôi tập trung vào ba điểm chính sau:

Thứ nhất, tôi cần một coroutine phi đối xứng (asymmetric coroutine), kiểu hoạt động tương tự như coroutine trong Lua mà nhiều lập trình viên đã quen thuộc. Thứ hai, người dùng không cần bận tâm về giới hạn kích thước stack như khi sử dụng các thư viện truyền thống. Điều này có nghĩa là mỗi coroutine có thể sử dụng không gian stack tương đương với thread chính. Cuối cùng, tôi yêu cầu footprint bộ nhớ cho mỗi coroutine phải cực kỳ tối ưu vì dự kiến sẽ chạy hàng ngàn coroutine đồng thời - điều không khả thi nếu mỗi coroutine chiếm vài megabyte bộ nhớ như nhiều thư viện hiện nay.

Phân tích kỹ hơn, trong ứng dụng của tôi, tại thời điểm xảy ra sự chuyển đổi coroutine (context switching), lượng dữ liệu trên stack không thực sự lớn. Dù các hàm thư viện được gọi bên trong coroutine có thể yêu cầu nhiều stack, nhưng những điểm chuyển đổi không nằm trong các hàm đó. Chính vì vậy, giải pháp copy stack tại thời điểm chuyển đổi hoàn toàn khả thi, dù chi phí cho mỗi lần switch có cao hơn chút đỉnh nhưng hoàn toàn chấp nhận được nhờ tần suất chuyển đổi không quá cao.

Phiên bản hiện tại mới chỉ hỗ trợ nền tảng Posix, nhưng việc porting sang Windows không hề phức tạp. Chỉ cần thay thế nhóm API setcontext bằng Fiber API là có thể hoàn tất quá trình chuyển đổi nền tảng. Đây sẽ là công việc ưu tiên trong tương lai gần khi có nhu cầu thực tế.

0%