2010-10-27 26 views
18

Tôi đang sử dụng hàng đợi để giao tiếp giữa các chuỗi. Tôi có một người đọc và nhiều chủ đề của người viết. Câu hỏi của tôi là tôi cần phải khóa hàng đợi mỗi khi tôi sử dụng push/front/pop từ hàng đợi cho người đọc? Tôi có thể làm một cái gì đó như sau:An toàn chủ đề cho hàng đợi STL

//reader threads 
getLock(); 
get the number of elements from the queue 
releaseLock(); 

int i = 0; 
while(i < numOfElements){ 
    queue.front(); 
    queue.pop(); 
    i++ 
} 

Ý tưởng là tôi muốn giảm bớt chi tiết của mã khóa và từ thread nhà văn sẽ chỉ viết vào mặt sau của hàng đợi và chỉ có một đầu đọc đơn chủ đề. Miễn là tôi nhận được số lượng các phần tử, sau đó tôi có thể lấy các phần tử từ hàng đợi HOẶC tôi có cần phải kèm theo số front()pop() trong khóa không?

Trả lời

8

Bất kỳ loại nào không tuyên bố rõ ràng sự đảm bảo an toàn chỉ nên luôn được kiểm soát bởi một mutex. Điều đó nói rằng, stdlib thực hiện của bạn có thể cho phép một số biến thể này - nhưng bạn không thể biết cho tất cả các triển khai của std :: queue.

Khi std :: queue kết thúc tốt hơn một vùng chứa khác (đó là bộ điều hợp vùng chứa), bạn cần phải nhìn vào vùng chứa cơ bản, mặc định là để loại bỏ.

Bạn có thể thấy dễ dàng hơn, tốt hơn hoặc di động hơn để viết bộ điều hợp vùng chứa của riêng bạn để đảm bảo bạn cần. Tôi không biết bất cứ điều gì làm điều này chính xác cho một hàng đợi trong Boost.

Tôi chưa xem xét C++ 0x đủ để biết nếu nó có bất kỳ giải pháp nào cho ra ngoài hộp này, nhưng đó có thể là một tùy chọn khác.

+4

C++ 0x có Atomics, vì vậy nó cho phép các lập trình viên để viết lock-free (thread-an toàn) các thuật toán, và cung cấp mutex tiêu chuẩn, nhưng nó không có bất cứ điều gì out-of-the-box. – GManNickG

2

Điều này hoàn toàn phụ thuộc vào việc triển khai thực hiện. Tiêu chuẩn C++ đề cập đến các chủ đề hoặc sự an toàn của luồng, vì vậy việc này có hoạt động hay không phụ thuộc vào cách thực thi của bạn xử lý các phần tử hàng đợi.

Trong trường hợp của bạn, trình đọc thực sự xuất hiện hàng đợi, được coi là thao tác ghi. Tôi nghi ngờ bất kỳ triển khai phổ biến thực sự đảm bảo an toàn thread trong trường hợp này, khi nhiều chủ đề đồng thời ghi vào một container. Ít nhất VC++ không:

Để đọc cùng một đối tượng, đối tượng là chủ đề an toàn khi đọc khi không có người viết trên chủ đề khác.

Để ghi vào cùng một đối tượng, đối tượng là chủ đề an toàn để viết từ một chuỗi khi không có người đọc nào trên các chủ đề khác.

9

Như những người khác đã đề cập, các bộ chứa tiêu chuẩn không bắt buộc phải đảm bảo an toàn luồng vì vậy những gì bạn yêu cầu không thể thực hiện được một cách hợp lý. Bạn có thể giảm thời gian luồng của người đọc đang khóa các nhà văn bằng cách sử dụng 2 hàng đợi và một con trỏ hàng đợi cho biết hàng đợi hiện đang được các nhà văn sử dụng.

Mỗi nhà văn sẽ:

  • khóa Acquire
  • Đẩy yếu tố (s) vào hàng đợi hiện được trỏ đến bởi con trỏ đợi
  • khóa phát hành

Người đọc sau đó có thể làm như sau:

  • Thu thập e khóa
  • Chuyển con trỏ đợi để trỏ đến hàng đợi thứ hai
  • khóa phát hành
  • yếu tố Process từ hàng đợi đầu tiên
+0

Nhà văn hoạt động như thế nào? – GManNickG

+2

Người viết sẽ luôn gắn thêm vào bất kỳ hàng đợi nào mà con trỏ hàng đợi hiện đang trỏ đến (sau khi đã mua khóa). Trong trường hợp này, khóa đang bảo vệ hàng đợi nào mà con trỏ hiện đang đề cập đến (và chính con trỏ); hàng đợi khác ("hàng đợi đầu tiên") có thể được người đọc xử lý bằng cách giữ khóa. –

1

Đôi khi bạn có thể giải quyết rất nhiều đồng thời đau đầu bằng cách tránh tình trạng chia sẻ hoặc nguồn lực trong chủ đề. Nếu bạn có nhiều luồng truy cập đồng thời một thùng chứa để đẩy vào công việc của chúng thì hãy cố gắng để chúng hoạt động trên các vùng chứa chuyên dụng. Tại các điểm cụ thể, bạn thu thập các phần tử của thùng chứa vào thùng chứa trung tâm theo cách không đồng thời.

Nếu bạn có thể tránh chia sẻ trạng thái hoặc tài nguyên giữa các luồng thì bạn không gặp vấn đề gì khi chạy đồng thời. Chủ đề sau đó không cần phải lo lắng về nhau, bởi vì chúng hoàn toàn bị cô lập và không có tác dụng gì với nhau.

1

Linh cảm của bạn là chính xác: Mặc dù bạn không thể đếm trên hàng đợi STD là chỉ an toàn, hàng đợi phải là chủ đề an toàn theo thiết kế.

Một lời giải thích tốt đẹp của lý do tại sao đó là trường hợp và triển khai chuẩn của đề an toàn, khóa hàng đợi miễn phí trong C++ được cho bởi van Dooren

+2

việc thực thi hàng đợi miễn phí ngây thơ chỉ là một phần "thread an toàn" chỉ dành cho nhà sản xuất đơn lẻ đặc biệt, người tiêu dùng đơn lẻ và một vài giả định về rào cản bộ nhớ và đọc/ghi nguyên tử trong mã do trình biên dịch tạo ra. Tuy nhiên nó có thể thực hiện thực sự khóa miễn phí hàng đợi an toàn thread nhưng nó không phải là đơn giản. – Leo

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