David Rodríguez - dribeas escribió en un comentario en StackOverflow que "No todas las colecciones se pueden implementar sin bloqueos". No estoy seguro de si esto es cierto, y no puedo encontrar pruebas de ninguna manera.
Esta declaración no es muy precisa, pero permítanme tratar de reformularla de una manera un poco más formal: para cada tipo de colección C
, existe un tipo de colección C
LF sin bloqueo que ofrece el mismo conjunto de operaciones, y donde cada operación en C
LF tiene la misma complejidad big-O que la operación correspondiente en C
.
No espero una transformación, por cierto.
LOCK
instrucciones de la CPU, sino el planificador de subprocesos, a través de mutexes / semaphores / etc.Respuestas:
Como estaba algo confundido, empiezo aclarando algunos conceptos en la pregunta.
Colección . No veo ninguna razón para pasar el tiempo definiendo rigurosamente lo que significa "colección" cuando simplemente podemos preguntar qué sucede con las estructuras de datos en general. Una estructura de datos ocupa un trozo de memoria y tiene algunas operaciones que pueden acceder a esa memoria y que los usuarios pueden invocar . Estos usuarios pueden ser procesadores distintos o simplemente hilos diferentes, no nos concierne. Lo único que importa es que puedan ejecutar operaciones en paralelo.
Sin bloqueo . Herlihy y Boss dicen que una estructura de datos está libre de bloqueos cuando un usuario que falla no impide usos adicionales de la estructura de datos. Por ejemplo, imagine que uno vierte agua en un procesador que está insertando un nodo en un conjunto ordenado. Bueno, si otros procesadores intentan insertarse más tarde en ese conjunto ordenado, deberían tener éxito. ( Edición: De acuerdo a esta definición, es el caso que si utiliza una estructura de datos cerraduras entonces no es lock-libre, pero es no el caso de que si una estructura de datos no utiliza las cerraduras entonces es libre de bloqueo).
Con esta definición, creo que Herlihy y Boss básicamente dicen que la respuesta es convertir las regiones críticas en transacciones.
Pero, usted puede preguntar, ¿tiene esto la misma complejidad? No estoy seguro de que la pregunta tenga sentido. Considere
push(x) { lock(); stack[size++] = x; unlock(); }
. ¿Es esta una operación de tiempo constante? Si ignora la operación de bloqueo y, por lo tanto, otros usuarios, puede responder SÍ. Si no desea ignorar a otros usuarios, entonces realmente no hay forma de decir si la inserción se ejecutará en tiempo constante. Si subes un nivel y ves cómo un algoritmo particular usa la pila, entonces podrías decir que el empuje siempre tomará un tiempo constante (medido ahora en términos de lo que sea que sea la entrada de tu algoritmo paralelo). Pero eso realmente es una propiedad de su algoritmo, por lo que no tiene sentido decir que push es una operación de tiempo constante.En resumen, si ignora cuánto espera un usuario que ejecuta una operación a otros usuarios, el uso de transacciones en lugar de regiones críticas responde a su pregunta afirmativamente. Si no ignora el tiempo de espera, debe observar cómo se utiliza la estructura de datos.
fuente
push
operación como se indicó anteriormente no es una operación de tiempo constante. Para un número fijo de procesadores, y una implementación comúnlock
que garantiza que no haya inanición, la operación anterior (en el peor de los casos, para cualquier procesador dado toma N_proc * O (1), que ingenuamente se puede suponer que es O (1) ( número de procesadores incluidos en la constante oculta.)Creo que "COLECCIONES" significa "colas, pilas, listas vinculadas, árboles, ..."
De http://www.cl.cam.ac.uk/research/srg/netos/lock-free/
Mediante un diseño e implementación cuidadosos, es posible construir estructuras de datos que sean seguras para uso concurrente sin necesidad de administrar bloqueos o subprocesos de bloque. Estas estructuras de datos sin bloqueo pueden aumentar el rendimiento al permitir una mayor concurrencia y pueden mejorar la robustez al evitar algunos de los problemas causados por la inversión de prioridad en la configuración local, o fallas de máquinas y enlaces en sistemas distribuidos.
La mejor introducción general a nuestros algoritmos sin bloqueo es la programación simultánea en papel sin bloqueos, actualmente en proceso de presentación, que cubre nuestros diseños de memoria transaccional de software basada en palabras de comparación y intercambio de varias palabras y memoria transaccional de software basada en objetos.
Si "sin bloqueo" significa "no use semáforos, mutex, monitores, ..." del sistema operativo, entonces creo (pero no soy un experto) que cada colección se puede hacer sin bloqueo usando lectura-escritura atómica modificar primitivas que deben ser compatibles con el hardware.
Se puede encontrar documentación exhaustiva sobre el tema en línea:
http://www.google.it/search?q=lock+free+algorithm+filetype%3Apdf
(... y más referencias al final de cada documento)
fuente