Muy buena pregunta. Estás tocando un caso muy interesante y común en concurrencia: quieres crear un grupo de hilos en un bucle, y que uno de ellos (por ejemplo el primero) espere hasta que todos los demás se hayan creado o iniciado antes de actuar. Esto no se resuelve solo con mutex. Veamos por partes:
c
CopiarEditar
for (int i = 0; i < N; i++) {
pthread_create(&threads[i], NULL, thread_func, (void*)(intptr_t)i);
}
Aquí, todos los hilos comienzan en paralelo, pero el orden de ejecución no está garantizado. El primer hilo creado puede empezar antes o después que los demás. No puedes controlar eso con un mutex directamente.
Aquí entra un mecanismo de sincronización diferente al mutex: un barrier, una condición o un contador con mutex.
pthread_barrier_t (la mejor para este caso)Un barrier es una estructura que permite que varios hilos esperen hasta que todos hayan llegado a un punto común antes de seguir.
c
CopiarEditar
#include <pthread.h>
#include <stdio.h>
#include <unistd.h>
#define N 4
pthread_barrier_t barrier;
void* thread_func(void* arg) {
int id = (int)(intptr_t)arg;
printf("Thread %d ready\n", id);
// Espera a que todos lleguen aquí
pthread_barrier_wait(&barrier);
// Después de que todos llegaron
if (id == 0) {
printf("Thread 0 toma acción luego de que todos estén listos\n");
} else {
printf("Thread %d continúa\n", id);
}
return NULL;
}
int main() {
pthread_t threads[N];
pthread_barrier_init(&barrier, NULL, N); // N hilos deben esperar
for (int i = 0; i < N; i++) {
pthread_create(&threads[i], NULL, thread_func, (void*)(intptr_t)i);
}
for (int i = 0; i < N; i++) {
pthread_join(threads[i], NULL);
}
pthread_barrier_destroy(&barrier);
return 0;
}
🔒 Todos los hilos esperan en pthread_barrier_wait() hasta que todos hayan llegado. Solo entonces avanzan todos simultáneamente.
pthread_cond_t y contador compartido (más flexible)Si quieres algo más fino (por ejemplo: que el hilo 0 espere hasta que N−1 hilos estén listos), puedes usar:
pthread_cond_t) para notificar al hilo 0.c
CopiarEditar
pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t cond = PTHREAD_COND_INITIALIZER;
int ready_threads = 0;
void* thread_func(void* arg) {
int id = (int)(intptr_t)arg;
pthread_mutex_lock(&mutex);
ready_threads++;
if (ready_threads == N) {
pthread_cond_signal(&cond); // último hilo avisa
}
pthread_mutex_unlock(&mutex);
if (id == 0) {
// espera a que los demás estén listos
pthread_mutex_lock(&mutex);
while (ready_threads < N) {
pthread_cond_wait(&cond, &mutex);
}
pthread_mutex_unlock(&mutex);
printf("Thread 0: Todos están listos, comienzo\n");
} else {
printf("Thread %d listo\n", id);
}
return NULL;
}