NOMBRE¶
futex - Bloqueos rápidos en espacio de usuario
SINOPSIS¶
#include <linux/futex.h>
DESCRIPCIÓN¶
El núcleo de Linux proporciona
futexes ('Fast Userspace muTexes')
como un componente básico para la construcción de bloqueos y
semáforos rápidos en espacio de usuario. Los
futexes son
un mecanismo muy básico y se prestan bien para construir abstracciones
de más alto nivel como mutexes POSIX.
Esta página no pretende documentar todas las decisiones de diseño
sino que se limita a cuestiones relevantes para el desarrollo de aplicaciones
y bibliotecas. De hecho, la mayoría de los programadores no
usarán
futexes directamente sino que en su lugar se
apoyarán en bibliotecas del sistema construídas sobre ellos,
como la implementación NPTL de pthreads.
Un
futex se identifica mediante un trozo de memoria que puede ser
compartido entre diferentes procesos. En estos procesos, el
futex no
necesita tener direcciones idénticas. En su forma más
básica, un
futex tiene la semántica de un
semáforo; es un contador que se puede incrementar y reducir de forma
atómica; los procesos pueden esperar a que el valor se vuelva positivo.
En el caso en el que no se produzca contienda, la operación
futex
se realiza enteramente en espacio de usuario. Al núcleo sólo se
le implica para arbitrar el caso de contienda. Al igual que en otros
diseños sensatos, los
futexes se han optimizado para evitar la
contención en la medida de lo posible.
En su forma más básica, un
futex es un entero alineado que
sólo se modifica mediante instrucciones atómicas en ensamblador.
Los procesos pueden compartir este entero a través de mmap, mediante
segmentos compartidos o usando el mismo espacio de memoria (en este
último caso se dice comúnmente que la aplicación es
multihilo).
SEMÁNTICA¶
Cualquier operación
futex se inicia en el espacio de usuario, pero
puede ser necesario comunicarse con el núcleo usando la llamada al
sistema
futex(2).
Para 'subir' un
futex, ejecute las instrucciones en ensamblador adecuadas
que harán que la CPU incremente atómicamente el entero. A
continuación, compruebe si realmente ha cambiado de 0 a 1, en cuyo caso
no había procesos esperando y la operación ha terminado. Este es
el caso sin contienda, que es rápido y debe ser el más
común.
En el caso de contienda, el incremento atómico cambió el contador
desde -1 (o algún otro número negativo). Si se detecta,
había procesos esperando. Ahora, desde el espacio de usuario, se debe
asignar un 1 al contador y ordenar al núcleo que despierte a cualquier
proceso que se encuentre esperando, usando para ello la operación
FUTEX_WAKE.
Esperar en un
futex, para 'bajarlo', es la operación contraria.
Reduzca atómicamente el contador y compruebe si ha cambiado a 0, en
cuyo caso no hay contienda y la operación ha terminado. En cualquier
otra circunstancia, el proceso debe asignar un -1 al contador y solicitar que
el núcleo espere a que otro proceso suba el
futex. Esto se hace
usando la operación FUTEX_WAIT.
A la llamada al sistema
futex(2) se le puede pasar opcionalmente un plazo
de tiempo que especifique cuánto tiempo debe esperar el núcleo a
que el
futex sea incrementado. En este caso, la semántica es
más compleja y se remite al programador a
futex(2) para obtener
más detalles. Lo mismo se aplica a las esperas asíncronas en
futex.
OBSERVACIONES¶
Insistimos, los
futexes, en su forma más básica, no
están pensados como abstracción sencilla para los usuarios
finales. Es de esperar que los implementadores sean buenos conocedores de
ensamblador y que hayan leído los fuentes de la biblioteca de
futex en espacio de usuario que se indica más abajo.
Esta página de manual ilustra el uso más común de las
primitivas
futex(2), aunque no es el único ni mucho menos.
AUTORES¶
Los
futexes fueron diseñados e implementados por Hubertus Franke
(IBM Thomas J. Watson Research Center), Matthew Kirkwood, Ingo Molnar (Red
Hat) y Rusty Russell (IBM Linux Technology Center). Esta página fue
escrita por Bert Hubert.
VERSIONES¶
El soporte inicial para
futex se añadió a la versión
2.5.7 de Linux pero con una semántica distinta a la descrita más
arriba. La semántica actual se encuentra disponible desde la
versión 2.5.40 de Linux.
VÉASE TAMBIÉN¶
futex(2), `Fuss, Futexes and Furwocks: Fast Userlevel Locking in Linux'
(actas del Ottawa Linux Symposium 2002), biblioteca de ejemplo de
futex, futex-*.tar.bz2
<
URL:ftp://ftp.kernel.org:/pub/linux/kernel/people/rusty/>.