2010-01-28 8 views
9

Tengo un montón de hilos que hacen mucha comunicación entre ellos. Preferiría esto estar libre de bloqueo.¿Es posible un solo productor y múltiples productores en una configuración sin bloqueo?

Para cada hilo, quiero tener un buzón, donde otros hilos pueden enviarle mensajes, (pero solo el propietario puede eliminar mensajes). Esta es una situación de consumidor único de múltiples productores. ¿es posible para mí hacer esto en un asunto sin bloqueo/alto rendimiento? (Esto está en el bucle interno de una simulación gigantesca).

Respuesta

3

Claro, si usted tiene una instrucción atómica CompareAndSwap:

for (i = 0; ; i = (i + 1) % MAILBOX_SIZE) 
{ 
    if ((mailbox[i].owned == false) && 
     (CompareAndSwap(&mailbox[i].owned, true, false) == false)) 
     break; 
} 

mailbox[i].message = message; 
mailbox[i].ready = true; 

Después de leer un mensaje, el hilo de consumir solo establece mailbox[i].ready = false; mailbox[i].owned = false; (en ese orden).

+1

necesita adquirir/liberar barreras de memoria en las configuraciones ready = true/false y owned = false. Al igual que en CompareAndSwap, pero generalmente eso es solo parte de la función. – tony

+0

Eso depende completamente de las reglas de ordenamiento de memoria de su arquitectura.Si las escrituras no se reordenan con respecto a otras escrituras emitidas desde el mismo procesador (que es común), entonces la barrera de memoria con 'CompareAndSwap' es suficiente para la corrección. – caf

0

es posible que desee ver los bloques de creación de subprocesos de Intel, recuerdo que una conferencia del desarrollador de Intel mencionó algo parecido.

2

Aquí hay un paper from the University of Rochester illustrating a non-blocking concurrent queue. El algoritmo descrito en el documento muestra una técnica para hacer una cola sin bloqueo.

+1

ConcurrentLinkedQueue de Java implementa el algoritmo en el documento, FYI. –

+0

Creo que es también, más o menos, la base para la implementación de ConcurrentQueue en .NET: http://blogs.msdn.com/pfxteam/archive/2010/01/26/9953725.aspx –

9

Cola libre de múltiples productores Única consumidora (MPSC) La cola es uno de los algoritmos de bloqueo más fáciles de implementar.

La implementación más básica requiere una simple lista de enlace único sin bloqueo (SList) con solo push() y flush(). Las funciones están disponibles en la API de Windows como InterlockedFlushSList() e InterlockedPushEntrySList() pero son muy fáciles de rodar por su cuenta.

Múltiples elementos de empuje del productor() en el SList usando un CAS (interbloqueo de comparación y cambio).

El consumidor individual hace un color() que intercambia el encabezado del SList con un NULL usando un intercambio XCHG (intercambio entrelazado). El consumidor tiene una lista de artículos en el orden inverso.

Para procesar los elementos en orden, simplemente debe invertir la lista devuelta por flush() antes de procesarla. Si no le importa el orden, simplemente puede recorrer la lista de inmediato para procesarlo.

Dos notas si saca sus propias funciones:

1) Si usted está en un sistema con pedidos de memoria débil (es decir, PowerPC), hay que poner una "liberación barrera de memoria" al principio del empuje() función y una "barrera de memoria aquire" al final de la función flush().

2) Puede simplificar y optimizar considerablemente las funciones porque el problema ABA con SLists ocurre durante la función pop(). No puede tener problemas ABA con un SList si solo usa push() y flush(). Esto significa que puede implementarlo como un único puntero muy similar al código sin bloqueo y no es necesario contar con un contador de secuencia de prevención de ABA.

+0

Siempre necesita barreras de adquisición/liberación (o liberación/adquisición de C++ 11 sin barreras globales), pero en x86 compilan cero instrucciones adicionales y solo evitan el reordenamiento en tiempo de compilación. http://preshing.com/20120625/memory-ordering-at-compile-time/. –

+0

Sí ... la ligera barrera de sincronización/compilación/adquisición/liberación es algo a tener en cuenta cada vez que se escribe código sin bloqueo. – Adisak

Cuestiones relacionadas