2014-06-20 18 views
11

Tiêu chuẩn mới :: shared_timed_mutex cho phép hai loại khóa: được chia sẻ và độc quyền.Có thể khóa chia sẻ trên std :: shared_timed_mutex được nâng cấp lên khóa độc quyền không?

Nếu có khóa chung, có cách nào để trao đổi nguyên tử ("nâng cấp") lên khóa độc quyền không? Nói cách khác, được đưa ra đoạn mã sau, làm thế nào tôi có thể tránh được việc thả và khóa lại không nguyên tử?

std::shared_timed_mutex m; //Guards a std::vector. 
m.lock_shared(); 

//Read from vector. (Shared lock is sufficient.) 
// ... 

//Now we want to write to the vector. We need an exclusive lock. 
m.unlock_shared(); 
        //  <---- Problem here: non-atomic! 
m.lock(); 

//Write to vector. 
// ... 

m.unlock(); 

Lý tưởng nhất, m.unlock_shared(); m.lock(); có thể được thay thế bằng một cái gì đó giống như m.upgrade_to_exclusive(); (hoặc một cái gì đó giống như boost::.upgrade_to_unique_lock()).

In a similar question but for Boost's shared_mutex Dave S đề cập

Không thể chuyển đổi từ một khóa chia sẻ cho một khóa độc đáo, hoặc một khóa chia sẻ một khóa có thể nâng cấp mà không nhả khóa chia sẻ đầu tiên.

Tôi không chắc chắn liệu điều này có áp dụng cho std :: shared_mutex hay không, mặc dù tôi nghi ngờ điều đó xảy ra.

Tôi sẽ hài lòng với một công việc hợp lý dựa trên std :: atomic/condition_variable hoặc bộ nhớ giao dịch của GCC.

Chỉnh sửa: Câu trả lời của Howard giải quyết câu hỏi của tôi. proposal N3427 chứa các mô tả hay về cơ chế để nâng cấp mutex. Tôi vẫn chào đón các work-around dựa trên std :: atomic/condition_variable hoặc bộ nhớ giao dịch của GCC.

Trả lời

13

Không, nó có thể không. Chức năng đó đã được đề xuất cho ủy ban dưới tên upgrade_mutexupgrade_lock, nhưng ủy ban đã chọn từ chối phần đó của đề xuất. Hiện tại, không có cách nào để thực hiện lại chức năng đó.

Sửa

Để đối phó với "đi đâu từ đây" chỉnh sửa trong câu hỏi user3761401, tôi đã tạo ra một thực hiện một phần tê liệt của upgrade_mutex/upgrade_lock đây:

https://github.com/HowardHinnant/upgrade_mutex

Hãy thoải mái để sử dụng điều này. Nó thuộc phạm vi công cộng. Nó chỉ được kiểm tra nhẹ, và nó không có đầy đủ chức năng được mô tả trong N3427. Cụ thể chức năng sau bị thiếu:

  • Không thể chuyển đổi unique_lock thành shared_timed_lock.
  • Người ta không thể thử hoặc hẹn giờ chuyển đổi shared_timed_lock thành unique_lock.
  • Người ta không thể thử hoặc chuyển đổi thời gian sang số upgrade_lock thành unique_lock.

Điều đó đang được nói, tôi đã đưa chức năng này vào upgrade_mutex và có thể truy cập ở mức thấp này theo cách rất xấu (ví dụ như trong main.cpp).

Các chuyển đổi khóa khác được đề cập trong N3427 khả dụng.

  • thử và chuyển đổi theo thời gian từ shared_timed_lock sang upgrade_lock.
  • chuyển đổi từ upgrade_lock thành shared_timed_lock.
  • chặn chuyển đổi từ upgrade_lock thành unique_lock.
  • chuyển đổi từ unique_lock thành upgrade_lock.

Tất cả đã được đặt trong namespace acme. Đặt nó vào bất kỳ không gian tên nào bạn muốn.

Yêu cầu

Trình biên dịch cần phải hỗ trợ "rvalue-này" vòng loại, và các nhà khai thác chuyển đổi rõ ràng.

Phủ nhận

Mã này đã được thử nghiệm chỉ nhẹ. Nếu bạn tìm thấy lỗi tôi sẽ đánh giá cao một yêu cầu kéo.

Có thể tối ưu hóa upgrade_mutex thông qua việc sử dụng std::atomic. Không có nỗ lực nào được thực hiện trên mặt trận đó (đó là một nhiệm vụ khó khăn và dễ bị lỗi, mất nhiều thời gian hơn tôi hiện tại).

+0

Cảm ơn thông tin chi tiết. Tôi thấy [đề xuất của bạn N3427] (http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2012/n3427.html), cụ thể là phần bắt đầu "Tổng quan về khóa nâng cấp" giải quyết vấn đề của tôi câu hỏi chính xác. Bạn có biết lý do cơ bản cho việc từ chối không? – user3761401

+1

Thật không may là tôi đã lỡ cuộc họp đó. Vì vậy, tôi không biết chi tiết. Nó cũng được đề xuất cho C++ 11 trong khung thời gian năm 2007, và bị từ chối vào thời điểm đó bởi vì chúng tôi cần loại bỏ tài liệu để chúng tôi có thể gửi C++ 09 đúng giờ (điều này không xảy ra). –

+0

@ user3761401 Có lẽ vì nó được mong muốn cho phép sao lưu 'shared_mutex' với' SRWLOCK', không cung cấp tính năng đó. –

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