Bạn có hai luồng, a và b. Thread a nằm trong vòng lặp mãi mãi, lắng nghe trên socket chặn 1. Thread b cũng nằm trong vòng lặp mãi mãi, lắng nghe trên socket socket 2. Cả socket 1 và socket 2 đều có thể trả về dữ liệu bất kỳ lúc nào, vì vậy Thread a có thể ngủ mãi mãi chờ đợi dữ liệu trong khi Thread b liên tục lấy dữ liệu từ socket và tiếp tục với quá trình xử lý của nó. Đó là nền tảng.Chủ đề Mô hình Truyền thông Chủ đề Haskell
Bây giờ giả sử họ cần chia sẻ một từ điển. Khi Thread a lấy một số dữ liệu (nếu có) nó sẽ thêm một cặp giá trị khóa vào từ điển sau khi xử lý một số, và sau đó tiếp tục chờ đợi thêm dữ liệu. Khi Thread b nhận dữ liệu từ socket của nó, đầu tiên nó sẽ truy vấn từ điển để xem có thông tin liên quan đến dữ liệu mà nó đã nhận trước khi tiếp tục với quá trình xử lý của nó hay không. Không có xóa cho từ điển, chỉ chèn và truy vấn (Tôi muốn được quan tâm nếu điều này làm cho một sự khác biệt trong các giải pháp cuối cùng).
Trong ngôn ngữ chuẩn bắt buộc như python hoặc c, điều này khá dễ thực hiện bằng cách đặt từ điển sẵn có ở cả hai phạm vi và chỉ truy vấn từ sau khi chuỗi đã có khóa.) cập nhật từ điển.
Trong Haskell, tôi dường như đang vật lộn để đưa ra một triển khai tốt về mẫu này. MVars, chỉ có thể có một mục tại một thời điểm, vì vậy nó không thể là Thread được đặt trong từ điển, vì bản cập nhật mới có thể xảy ra và nó sẽ không thể đẩy từ điển mới cho đến khi Thread b lấy nó từ MVar. Mặt khác, nếu thread b sử dụng một MVar để gửi tín hiệu sẵn sàng "ok!" vào luồng a, có thể là trường hợp mà Thread a đang ngủ trên ổ cắm đọc của nó, vì vậy nó sẽ không thể gửi dữ liệu trở lại cho đến khi socket được bỏ chặn của nó được bỏ chặn! Ngoài ra còn có các kênh, nhưng điều đó có vẻ lộn xộn vì tôi sẽ phải tiếp tục gửi các bộ từ điển mới và Chủ đề B sẽ loại bỏ tất cả trừ những cái cuối cùng.
Giải pháp thay thế có thể hoạt động là chỉ cần gửi cập nhật xuống kênh và yêu cầu B tạo từ điển cho chính nó. Tuy nhiên tôi tự hỏi nếu có giải pháp thay thế tốt hơn.
Cảm ơn bạn đã dành thời gian đọc câu hỏi rất dài này!
Tôi không thấy vấn đề với 'MVar'. Nếu A được đánh thức và nhận dữ liệu mới, nó sẽ cố gắng 'takeMVar' từ điển từ' MVar'.Khi nó thành công, hãy cập nhật từ điển, từ điển 'putMVar', trở lại chế độ ngủ. Khi B nhận dữ liệu, hãy thử 'takeMVar', tra cứu xem lại. Nó bị hỏng ở đâu? –
Cảm ơn! Bắn Xin lỗi đó là chính xác những gì tôi đang tìm kiếm, không bao giờ. Tôi vẫn còn là một người bắt đầu. Tôi đã nghĩ rằng nó không thể lấy ra nếu nó được đưa vào, và chỉ có một sợi khác có thể. Giả định ngu ngốc ở sau đầu tôi! Tôi không chắc chắn làm thế nào để đóng câu hỏi này ngay bây giờ? –
Tôi có thể làm cho nó một câu trả lời mà bạn có thể chấp nhận để đánh dấu vấn đề là giải quyết, hoặc bạn có thể xóa câu hỏi nếu bạn thích (Tôi không biết làm thế nào, nên có một liên kết xóa ở đâu đó, tôi tin). –