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:


🧠 1. ¿Qué pasa si creas varios hilos en un bucle?

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.


✅ 2. ¿Qué hacer si el primer hilo necesita esperar a que los demás estén listos?

Aquí entra un mecanismo de sincronización diferente al mutex: un barrier, una condición o un contador con mutex.


🔹 Opción A: usar 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.


🔹 Opción B: usar 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:

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;
}