2010-10-13 7 views
15

Trong thời gian chạy đồng thời được giới thiệu trong VS2010, có một lớp concurrent_queue. Nó có hàm try_pop() không bị chặn.
Tương tự trong Intel Building Building Blocks (TBB), lệnh chặn pop() đã bị xóa khi chuyển từ phiên bản 2.1 sang 2.2.tại sao concurrent_queue không chặn?

Tôi tự hỏi có vấn đề gì với cuộc gọi chặn. Tại sao nó bị xóa khỏi TBB? Và tại sao không có concurrent_queue chặn?

Tôi đang ở trong tình huống mà tôi cần một hàng đợi đồng thời chặn và tôi không muốn một sự chờ đợi bận rộn. Ngoài việc tự viết một hàng đợi, có khả năng nào khác trong thời gian chạy đồng thời không?

Trả lời

25

Từ a comment from Arch Robison, và nó không có được nhiều hơn nữa "horse's mouth" hơn (a):


PPL của concurrent_queue không có người chặn pop, do đó cũng như thế tbb::strict_ppl::concurrent_queue. Chặn chặn có sẵn trong tbb::concurrent_bounded_queue.

Đối số thiết kế bỏ qua chặn pop là trong nhiều trường hợp, đồng bộ hóa chặn được cung cấp bên ngoài hàng đợi, trong trường hợp việc thực hiện chặn bên trong hàng đợi sẽ trở thành phí không cần thiết.

Mặt khác, cửa sổ chặn của tbb::concurrent_queue cũ phổ biến trong số những người dùng không có đồng bộ hóa bên ngoài.

Vì vậy, chúng tôi chia chức năng. Các trường hợp sử dụng không cần chặn hoặc bị chặn có thể sử dụng tbb::concurrent_queue mới và các trường hợp sử dụng cần thiết có thể sử dụng tbb::concurrent_bounded_queue.


(a) Arch là kiến ​​trúc sư của khối xây dựng luồng.

4

Nếu bạn cần một cửa sổ chặn không bận, bạn cần có phương thức báo hiệu. Điều này ngụ ý sự đồng bộ giữa pusher và poper và hàng đợi không còn nguyên gốc đồng bộ hóa (đắt tiền) nữa. Về cơ bản, bạn có được một hàng đợi được đồng bộ hóa bình thường với một biến điều kiện được sử dụng để thông báo cho những người mua hàng đẩy, mà không phải là trong các bộ sưu tập concurrent_ *.

0

Không có tình huống nào, từ quan điểm của hàng đợi, rằng cần cần để chặn chèn hoặc xóa. Thực tế là bạn có thể cần phải chặn và chờ đợi một chèn là không quan trọng.

Bạn có thể đạt được chức năng mà bạn mong muốn bằng cách sử dụng biến điều kiện hoặc semaphore đếm hoặc thứ gì đó dọc theo các dòng đó (bất kể API cụ thể của bạn cung cấp). Vấn đề của bạn không phải là việc chặn/không chặn; nó giống như một người tiêu dùng sản xuất cổ điển.

+2

Với chặn 'pop', bạn có thể thực hiện * * "cổ điển sản xuất-tiêu dùng" sử dụng TBB trong khoảng hai dòng mã, mà không cần phải viết bất kỳ nguyên thủy đồng bộ hóa chính mình. (Người tiêu dùng có 'trong khi (đúng) tiêu thụ (Q.pop());' và nhà sản xuất làm 'trong khi (đúng) Q.push (produce()); '.) Nếu không có một' pop' chặn, cùng một vấn đề yêu cầu ít nhất hai lần nhiều mã: cụ thể là, lưu giữ sổ sách biến số điều kiện bổ sung trên mỗi hàng đợi. Nhưng như paxdiablo nói, 'tbb :: concurrent_bounded_queue' tiếp tục cung cấp chức năng chặn' pop', và về cơ bản là một thay thế thả cho 'concurrent_queue'. – Quuxplusone

2

Câu hỏi đặt ra là nếu có một tùy chọn khác trong Thời gian chạy đồng thời cung cấp chức năng chặn hàng đợi vì concurrent_queue không có và có một trong VS2010.

Nhận xét của Arch dĩ nhiên là chính xác, chặn hàng đợi và bỏ chặn hàng đợi là các trường hợp sử dụng riêng biệt và đây là lý do tại sao chúng khác nhau trong VS2010 và trong TBB.

Trong VS2010 bạn có thể sử dụng lớp template unbounded_buffer nằm trong, các phương thức thích hợp được gọi là enqueue và dequeue.

-Rick