2013-04-24 23 views
8

Tôi có một lớp ConcurrentQueue đó là dựa trên một người dùng cung cấp container với một constructor như thế này ...Làm cách nào để khóa một mutex trong danh sách bộ khởi tạo?

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) {} 

Nhưng, tôi cần phải khóa other 's mutex trong khi nó đang được sao chép.

Lựa chọn 1:

Vì vậy, tôi có thể không sử dụng các nhà xây dựng bản sao nào cả, và làm ...

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.m_Queue) 
{ 
    std::lock_guard<std::mutex> lock(other.m_Mutex); 
    m_Queue = other.m_Queue; 
} 

Nhưng tôi không thể đảm bảo rằng nhiệm vụ sao chép và sao chép xây dựng tương đương chức năng.

Phương án 2:

tôi có thể có một phương pháp riêng ...

std::queue<T, Container> GetQueue() const 
{ 
    std::lock_guard<std::mutex> lock(other.m_Mutex); 
    return m_Queue; 
} 

Và sau đó trong các nhà xây dựng làm điều này ...

ConcurrentQueue(const ConcurrentQueue& other) : m_Queue(other.GetQueue()) {} 

Nhưng điều này có khả năng (tùy thuộc vào việc tối ưu hóa) sử dụng hàm tạo bản sao của m_Queue một lần và nó là hàm tạo di chuyển một lần. Và tôi cũng không thể đảm bảo rằng bản sao và di chuyển tương đương với một bản sao. Ngoài ra, thùng chứa do người dùng cung cấp có thể kỳ quái và có thể sao chép được nhưng không thể điều khiển được, điều này cũng sẽ khiến phương pháp này gặp sự cố.

Vì vậy, tôi phải làm gì?

Trả lời

9
ConcurrrentQueue::ConcurrrentQueue(
     ConcurrrentQueue const& other) 
    : m_Queue((std::lock_guard<std::mutex>(other.m_Mutex), 
       other.m_Queue)) 
{ 
} 

sẽ hoạt động.

+0

Bạn có nghĩ rằng nó luôn luôn được thực hiện theo cách này không? – 0x499602D2

+0

@ 0x499602D2 Thực ra, tôi nghĩ rằng tình huống nên tránh. Tôi không biết đủ bối cảnh thực tế của bạn, hoặc vấn đề bạn đang cố gắng giải quyết, để đề xuất các giải pháp thay thế, nhưng tôi biết rằng tôi chưa bao giờ phải thực sự sử dụng một cái gì đó như thế này. Trong thực tế, tôi không thể thực sự nghĩ về một trường hợp mà tôi đã sao chép một container giữa các chủ đề. –

1

Khóa, tạo bản sao nội dung và sau đó trao đổi nội dung với thành viên. Ít nhất đó là cách dễ nhất và dễ nhất của IMHO. Một cách ít gọn gàng hơn là sử dụng toán tử dấu phẩy: (a, b) sản lượng b, nhưng nếu a là khóa vi phạm, tạm thời sẽ tồn tại cho đến điểm tiếp theo, tức là cho đến khi bạn sử dụng b để khởi tạo bản sao cục bộ của mình.

Điều đó nói rằng, có hai điều cần xem xét:

  • Có lẽ sao chép không phải là một ý tưởng thông minh như thế nào và thiết kế của bạn hoạt động cũng như nếu bạn chỉ vô hiệu hóa sao chép.
  • Nếu bạn có quyền truy cập vào hàng đợi và bạn có thể đọc nó để sao chép, điều đó có nghĩa là mutex đã bị khóa chưa? Nếu không, làm thế nào bạn chắc chắn rằng bạn thực sự muốn sao chép hàng đợi? Tôi không nghi ngờ rằng có những câu trả lời để biện minh cho thiết kế, nhưng nó không bình thường.
Các vấn đề liên quan