[C con Clase] Problema sincronizacion hilos POSIX

Jorge Vega Sanchez memmaker650 en gmail.com
Mie Ago 11 13:12:41 CEST 2010


Estoy haciendo una prueba para sincronizar 2 hilos (pthreads). Lo que ando buscando es crear una barrera en ambos hilos para que a partir de allí ambos hilos se ejecuten al mismo tiempo.

EL problema es que no entiendo que falla.
Programa Principal.
Código
#include <pthread.h>
#include <stdio.h>
#include "procedimientos.h"
#include "barrier.h"
 
int contador = 0;
struct thdata
{
		int thread_no[2]; 
		char message[100];
		barrier_t *barrier;
};
 
int main()
{
	/* Identificador del thread hijo */
	pthread_t idHilo[2];
	thdata shared_data;         
	pthread_attr_t attr;
	barrier_t barrier;
 
	/* error devuelto por la función de creación del thread */
	int error[2];
 
	shared_data.thread_no[0] = 1;
	shared_data.thread_no[1] = 2;
	shared_data.barrier= &barrier;
 
	barrier_init(&barrier, 3);
 
	pthread_attr_init(&attr);
	pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
 
	error[0] = pthread_create (&idHilo[0], NULL, funcionThread1, (void *) &shared_data);
	error[1] = pthread_create (&idHilo[1], NULL, funcionThread2, (void *) &shared_data);
 
	/* Comprobamos el error al arrancar el thread */
	if (error[0] != 0)
	{
		printf("No puedo crear thread");
		return -1;
	}
 
	/* Bucle infinito para incrementar el contador y mostrarlo en pantalla */
	pthread_attr_destroy(&attr); 
	barrier_cross(&barrier);
 
	pthread_join(idHilo[0], NULL);
	pthread_join(idHilo[1], NULL);
 
	return 0;
}

- Diseño para la barrera
Estructura barrera
Código
typedef struct barrier 
{
  pthread_cond_t complete;
  pthread_mutex_t mutex;
  int count;
  int crossing;
} barrier_t;
Funciones
Código
 /* ################################################################### *
 * BARRIER
 * ################################################################### */
#include <pthread.h>
#include "barrier.h"
 
void barrier_init(barrier_t *b, int n)
{
  pthread_cond_init(&b->complete, NULL);
  pthread_mutex_init(&b->mutex, NULL);
  b->count = n;
  b->crossing = 0;
}
 
void barrier_cross(barrier_t *b)
{
  pthread_mutex_lock(&b->mutex);
    b->crossing++;
  
  if (b->crossing < b->count) {
    pthread_cond_wait(&b->complete, &b->mutex);
  } else {
    pthread_cond_broadcast(&b->complete);
    b->crossing = 0;
  }
  pthread_mutex_unlock(&b->mutex);
}

Y finalmente funciones que ejecutan los hilos.

Funciones

Código
#include <pthread.h> 
#include "procedimientos.h"
#include "barrier.h"
#include <unistd.h>     
#include <sys/types.h>   
#include <errno.h>      
#include <stdio.h>      
#include <stdlib.h>     
#include <string.h>    
#include <assert.h>
#include <getopt.h>
#include <limits.h>
 
struct thdata
{
		int thread_no[2]; 
		char mensaje[100];
		barrier_t *barrier;
};
 
void *funcionThread1 (void *ptr)
{
	thdata *data;            
    data = (thdata *)ptr; // Datos que mandamos al hilo
 
    printf("hilo 1");
 
    sleep(3);
	barrier_cross(data->barrier); // Barrera usada para sincronizacion
	printf("Arriba hilo 1");
 
	pthread_exit(0); 
}
void *funcionThread2 (void *ptr)
{
	thdata *data;            
    data = (thdata *)ptr; 
 
    printf("hilo 2");
 
	barrier_cross(data->barrier);
        sleep(1);
	printf("Despierta hilo 2");
 
	pthread_exit(0); 
}

En este último fichero sobran librerías incluidas pero no recordaba que librería contiene la función sleep y meti unas cuantas que tenía en otro programa.

No incluye los ficheros de cabecera porque son "triviales".

Solución obtenida con ese código.

Se produce el sleep durante 3 segundos  y psoteriormente se muestra todo seguido por pantalla.

Solucion deseada:

Salidas en pantalla:
hilo 1
hilo2
-- nada durante 3 segundos
arriba hilo 1
--espera un segundo - diferencial
Depierta hilo 2


El problema creo que está en las funciones del barrier pero  no consigo hacerlo funcionar bien.

Gracias de antemano, cualquier ayuda será bienvenida.
------------ próxima parte ------------
Se ha borrado un adjunto en formato HTML...
URL: <http://listas.conclase.net/pipermail/cconclase_listas.conclase.net/attachments/20100811/801e263b/attachment.html>


Más información sobre la lista de distribución Cconclase