2010-10-13 13 views
15

En el tiempo de ejecución de concurrencia introducido en VS2010, hay una clase concurrent_queue. Tiene una función try_pop() sin bloqueo.
Similar en Intel Thread Building Blocks (TBB), la llamada pop() de bloqueo se eliminó al pasar de la versión 2.1 a la versión 2.2.¿Por qué concurrent_queue no bloquea?

Me pregunto cuál es el problema con una llamada de bloqueo. ¿Por qué fue eliminado de TBB? ¿Y por qué no hay bloqueo concurrent_queue?

Estoy en una situación en la que necesito una cola concurrente de bloqueo, y no quiero una espera ocupada. Además de escribir una cola, ¿hay alguna otra posibilidad en el tiempo de ejecución de simultaneidad?

Respuesta

25

De a comment from Arch Robison, y no es mucho más que eso "horse's mouth"(a):


de PPL concurrent_queue no tiene pop bloqueo, por lo tanto, tampoco lo hace tbb::strict_ppl::concurrent_queue. El pop de bloqueo está disponible en tbb::concurrent_bounded_queue.

El argumento de diseño para omitir el bloqueo de pop es que en muchos casos, la sincronización para el bloqueo se proporciona fuera de la cola, en cuyo caso la implementación del bloqueo dentro de la cola se convierte en una sobrecarga innecesaria.

Por otro lado, el pop de bloqueo del antiguo tbb::concurrent_queue era popular entre los usuarios que no tenían sincronización externa.

Así que hemos dividido la funcionalidad. Los casos de uso que no necesitan bloqueo o acotación pueden usar el nuevo tbb::concurrent_queue, y los casos de uso que lo necesiten pueden usar tbb::concurrent_bounded_queue.


(a) arco es el arquitecto de Threading Building Blocks.

4

Si necesita un bloqueo pop sin una espera ocupada, necesita un método de señalización. Esto implica sincronización entre empujador y poper y la cola ya no tiene primitivas de sincronización (costosas). Básicamente, se obtiene una cola sincronizada normal con una variable de condición que se usa para notificar poppers de push, lo cual no está en la espiritu de las colecciones concurrent_ *.

0

No hay ninguna situación, desde el punto de vista de la cola, que deba necesitar para bloquear para insertar o quitar. El hecho de que deba bloquear y esperar un inserto es irrelevante.

Puede lograr la funcionalidad que desee mediante el uso de una variable de condición, o un semáforo de conteo, o algo similar (cualquiera que sea su API específica). Tu problema no es con bloqueo/no bloqueo; suena como un productor-consumidor clásico.

+2

Con un 'pop' bloqueo, se puede poner en práctica * * "clásico productor-consumidor" por medio de TBB en cerca de dos líneas de código, sin necesidad de escribir ningún primitivas de sincronización usted mismo. (El consumidor hace 'while (true) consume (Q.pop());' y el productor hace 'while (true) Q.push (produce());'.) Sin un bloqueo 'pop', el mismo problema requiere al menos el doble de código: a saber, la contabilidad una variable de condición adicional por cola. Pero como dice paxdiablo, 'tbb :: concurrent_bounded_queue' continúa proporcionando la funcionalidad de bloqueo' pop', y es básicamente un reemplazo directo para 'concurrent_queue'. – Quuxplusone

2

La pregunta era si había otra opción en el tiempo de ejecución de concurrencia que proporciona funcionalidad de cola de bloqueo porque concurrent_queue no y hay uno en VS2010.

El comentario de Arch es por supuesto completamente correcto, las colas de bloqueo y las colas de desbloqueo son casos de uso separados y es por eso que son diferentes en VS2010 y en TBB.

En VS2010 puede usar la clase de plantilla unbounded_buffer ubicada en, los métodos apropiados se llaman en cola y dequeue.

-Rick

Cuestiones relacionadas