2010-01-01 11 views
5

Windows Mutex parece permitir que se vuelva a adquirir un bloqueo adquirido (recursivamente) si el hilo que actualmente posee el bloqueo intenta adquirirlo.¿Cómo alterar el comportamiento de bloqueo recursivo de Windows Mutex?

Pero, los bloqueos pthread basados ​​en posix no permiten este tipo de comportamiento.

¿Hay alguna macro de tiempo de compilación o cualquier configuración que pueda hacer que las ventanas mutex se comporten de la misma manera que pthread mutex?

Respuesta

6

Mientras se programa en Windows, evitar reimplementar el comportamiento de su objeto mutex. Ser reentrante por el mismo hilo es absolutamente esencial para su comportamiento definido.

Un objeto de sincronización sin afinidad de hilos es un semáforo que cuenta para 1. Use CreateSemaphore().

Fwiw, es muy curioso que necesite este tipo de comportamiento. Parece que estás intentando utilizar el mismo objeto de sincronización en varios lugares de forma inapropiada. Puedes usar el semáforo pero perderás el potencial de concurrencia. Considere usar más de un mutex en su lugar.

+0

En realidad, tengo este problema relacionado con el código heredado y quiero resolverlo sin cambiar gran parte de la lógica. Entonces, quería saber si el comportamiento puede ser alterado. Mi código debería funcionar en múltiples sistemas operativos, por lo que quiero que el comportamiento permanezca igual en todo el sistema operativo. "Parece que estás intentando utilizar el mismo objeto de sincronización en varios lugares de forma inapropiada". - Sí. Es el caso de un escenario negativo. Solo quiero que el comportamiento sea el mismo en todos los SO en el escenario negativo. Gracias por su respuesta! – Jay

+1

Bueno, use un semáforo de refuerzo. Multiplataforma y no reentrante. –

+0

+1 (el comentario de seguimiento es tan bueno como la respuesta). – WhozCraig

0

Echa un vistazo a este artículo en 'fast mutex'.

Este tipo de mutelas no se pueden adquirir recursivamente.

¡Por supuesto, usted tendría que mirar en la forma de implementarlos en C.

+0

El soporte Fast Mutex está destinado a controladores, no a código de modo de usuario. – gavinb

6

No se puede modificar el hecho de que los Mutexes de Windows son recursivos. Y aunque los hilos de Posix no son recursivos por defecto, puede puede usar pthread_mutexattr_settype() con el indicador PTHREAD_MUTEX_RECURSIVE para hacer uno.

El bloqueo de un mutex en Windows es en realidad una operación bastante costosa, y se adapta mejor a la sincronización entre procesos. Para un mutex utilizado solo dentro de un proceso único, normalmente se utiliza una sección crítica, sin embargo, estos también son reentrantes. Como dice nobugz, necesitarías usar un semáforo, inicializado con un conteo máximo de 1, para obtener sincronización no recursiva.

Un objeto de semáforo es como un contador especial, que puede incrementarse y decrementarse atómicamente a través de subprocesos (o procesos, si se crean compartidos). Al crear uno con un recuento máximo de 1, obtiene el comportamiento no recursivo que necesita.

+0

La sección crítica PUEDE ingresarse nuevamente desde el mismo hilo. http://msdn.microsoft.com/en-us/library/ms682608(VS.85).aspx – arke

+0

Gracias por atrapar ese ¡Vaya !, solucionó la respuesta en consecuencia. – gavinb

2

Es mejor utilizar Read/Write locks (aka SRW). Al igual que Windows Mutex, no son recursivos. Al igual que las Secciones críticas, son livianas y no llaman al kernel si están libres (Benchmarks).

Cuestiones relacionadas