2012-04-21 7 views
5

Estoy usando pthread_mutex_trylock para bloquear el mutex en una estructura de modo que solo pueda accederse/modificarse mediante un único hilo en un momento dado. Si el mutex ya está bloqueado, simplemente regreso de la rutina en lugar de poner en cola/bloquear.bloques `pthread_mutex_trylock` cuando son llamados por dos hilos al mismo tiempo

Este es un esquema básico de mi código:

typedef struct { 
    pthread_mutex_t m; 
} myStruct; 

void setupStruct(myStruct* struc) { 
    pthread_mutex_init(&struc->m, NULL); 
} 

void structOp(myStruct* struc) { 

    printf("structOp(): Trying to lock\n"); 

    if(pthread_mutex_trylock(&struc->m) != 0) { 
     printf("structOp(): Lock failed\n"); 
     return; 
    } else { 
     printf("structOp(): Locked\n"); 
     // do some stuff to struct 
     pthread_mutex_unlock(&struc->m); 
    } 
} 

La estructura se inicializa una vez como esto:

myStruct* struc = malloc(sizeof(struc)); 
setupStruct(struc); 

Sin embargo, a veces, cuando dos hilos de llamar a una rutina que al mismo tiempo las dos llamadas a trylock parecen bloquear. Estoy asumiendo esto porque imprime "Trying to lock" para ambos hilos al mismo tiempo, pero no imprime si el mutex estaba bloqueado o no. Originalmente tenía este problema con pthread_mutex_lock, así que probé la versión sin bloqueo por este motivo, pero parece que aún bloquea.

Esto no siempre sucede, pero cuando lo hace siempre es el primeras dos llamadas a la rutina. Si las dos primeras llamadas funcionan bien, las llamadas siguientes también funcionan bien.

¿Hay alguna razón para bloquear esto? ¿Estoy percibiendo incorrectamente este bloqueo debido a algún otro problema? Puedo publicar otras partes de mi código si el problema puede estar en otra parte.

+1

no hay ninguna razón para que esto bloquear, que yo sepa. Algo probablemente sea incorrecto en otro lado. – Mat

+1

¿Qué llama a setupStruct()? No es llamado más de una vez, por casualidad? –

+0

Definitivamente solo se llama una vez, justo antes de que se inicien los nuevos hilos. Creo que si hay un problema, lo más probable es con mi uso de punteros. ¿Estos parecen correctos? Estoy asignando la estructura con 'myStruct * struc = malloc (sizeof (estructura));'. Actualizaré la pregunta con esta información. – Matt

Respuesta

8

Esta línea está mal:

myStruct* struc = malloc(sizeof(struc)); 

No alloate memoria suficiente, por lo que es probable que destrozar/reutilización de la memoria donde se accede a mutex. Usando sizeof(struc) asigna memoria para el tipo de struc, y el tipo de struc es un myStruct*, por lo que sólo estamos asignar memoria suficiente para almacenar un puntero (ielikely sólo 4 u 8 bytes)

Debe hacer

myStruct* struc = malloc(sizeof *struc); 

o

myStruct* struc = malloc(sizeof(myStruct)); 
+0

Guau, he estado asignando mal mis estructuras durante mucho tiempo ... ¡gracias por explicarme! – Matt

0

Esto es algún tipo de problema de sincronización o daños en la memoria. De cualquier manera, no está relacionado con el código que publicaste, por lo que no hay forma de responder a esta pregunta.

Si su sistema operativo admite valgrind, verifique su aplicación con los módulos memcheck y helgrind.

Cuestiones relacionadas