2009-07-24 35 views
7

Kịch bản của tôi: một máy chủ và một số máy khách (mặc dù không nhiều). Máy chủ chỉ có thể phản hồi một khách hàng tại một thời điểm, vì vậy chúng phải được xếp hàng đợi. Tôi đang sử dụng một mutex (boost::interprocess::interprocess_mutex) để làm điều này, được bọc trong một boost::interprocess::scoped_lock. Điều này là, nếu một khách hàng chết bất ngờ (tức là không có destructor nào chạy) trong khi đang nắm giữ mutex, các khách hàng khác đang gặp rắc rối, bởi vì họ đang chờ đợi trên mutex đó. Tôi đã xem xét sử dụng thời gian chờ đợi, vì vậy nếu tôi khách hàng chờ đợi, nói rằng, 20 giây và không nhận được mutex, nó đi trước và nói chuyện với máy chủ anyway.Làm cách nào để có quyền sở hữu một quảng cáo bị bỏ qua :: interprocess :: interprocess_mutex?

Các vấn đề với cách tiếp cận này: 1) nó thực hiện việc này mọi lúc. Nếu nó trong một vòng lặp, nói chuyện liên tục với máy chủ, nó cần phải chờ thời gian chờ mỗi lần duy nhất. 2) Nếu có ba khách hàng, và một trong số họ chết trong khi giữ mutex, hai người kia sẽ chỉ chờ 20 giây và nói chuyện với máy chủ cùng một lúc - chính xác những gì tôi đang cố gắng tránh.

Vì vậy, làm cách nào tôi có thể nói với khách hàng ", ở đó, có vẻ như đột biến này đã bị hủy, hãy sở hữu nó"?

+2

Nếu bạn đang dựa vào khách hàng để thực hiện đồng bộ hóa, bạn đang làm việc đó ngược. Bạn thực sự nên sửa chữa máy chủ của bạn để nó có thể chấp nhận nhiều kết nối, ngay cả khi nó chỉ làm cho các kết nối khác chờ đợi trong khi nó phục vụ một tại một thời điểm. Điều đó cho phép bạn lấy phần * interprocess * ra khỏi phương trình. –

+0

Điểm công bằng. Tuy nhiên, ứng dụng của tôi ban đầu được chỉ định là chỉ có một khách hàng tại một thời điểm - tôi chỉ mới gần đây (như trong ngày hôm nay) phát hiện ra rằng có thể có nhiều khách hàng. Tôi đã cố gắng giải quyết nó một cách dễ dàng, nhưng tôi cho rằng tôi sẽ phải nghĩ ra điều gì đó tinh vi hơn. –

+0

Dường như toàn bộ cơ chế của mutex là thiếu sót mà không có cơ chế phục hồi. Ước muốn tăng cường sửa lỗi này. – balki

Trả lời

6

Thật không may, điều này không được hỗ trợ bởi API tăng :: interprocess API. Tuy nhiên, có một vài cách bạn có thể thực hiện nó:

Nếu bạn đang sử dụng nền tảng POSIX có hỗ trợ pthread_mutexattr_setrobust_np, hãy chỉnh sửa tăng/interprocess/sync/posix/thread_helpers.hpp và tăng/interprocess/sync/posix/interprocess_mutex. hpp để sử dụng mutexes mạnh mẽ, và để xử lý bằng cách nào đó EOWNERDEAD trở về từ pthread_mutex_lock.

Nếu bạn đang ở trên một số nền tảng khác, bạn có thể chỉnh sửa tăng/interprocess/sync/thi đua/interprocess_mutex.hpp để sử dụng bộ đếm thế hệ, với cờ bị khóa ở bit thấp hơn. Sau đó, bạn có thể tạo giao thức xác nhận lại sẽ đặt cờ trong từ khóa để biểu thị xác nhận quyền sở hữu đang chờ xử lý, sau đó thực hiện so sánh và hoán đổi sau khi hết giờ để kiểm tra xem cùng một thế hệ vẫn còn trong từ khóa hay không và nếu có thay thế nó với giá trị thế hệ tiếp theo bị khóa.

Nếu bạn đang ở trên cửa sổ, một lựa chọn tốt khác là sử dụng các đối tượng mutex gốc; họ có thể sẽ hiệu quả hơn bận rộn chờ đợi.

Bạn cũng có thể muốn xem xét lại việc sử dụng giao thức bộ nhớ dùng chung - tại sao không sử dụng giao thức mạng thay thế?

+0

Câu trả lời hay. Tôi không nghĩ rằng tôi sẽ thực hiện nó, mặc dù; nó không có vẻ đáng để giải quyết rắc rối - tôi sẽ nghĩ về một thứ khác. Về đề xuất của bạn về việc sử dụng giao thức mạng, tôi không thể đồng ý với bạn nhiều hơn. Thật không may, nó chỉ là quá muộn trong trò chơi để thay đổi mọi thứ một cách triệt để. –

Các vấn đề liên quan