2012-07-18 8 views
5

Estoy tratando de encontrar la forma de deshacerme de la dependencia de pthread_timedjoin_np porque estoy tratando de construir algún código en OSX.alternativa a pthread_timedjoin_np

Ahora tengo una cola de hilos de la que estoy saliendo, haciendo pthread_timedjoin_np y si no regresan, se vuelven a colocar en la cola.

El final de la función thread_ que se llama para cada subproceso tiene un pthread_exit (0); para que el hilo de recepción pueda verificar un valor de retorno de cero.

Pensé que podría intentar usar pthread_cond_timedwait() para lograr un efecto similar, sin embargo, creo que me falta un paso.

pensé que iba a ser capaz de hacer subproceso de trabajo Una señal de una condición y pthread_exit() dentro de un mutex, y un trabajador Tema B podría despertar en la señal, y luego pthread_join(). El problema es que el hilo B no sabe qué hilo arrojó la señal condicional. ¿Debo pasar esto explícitamente como parte de la señal de condiciones o qué?

Gracias

Derek

+0

No es un duplicado, pero algunas de las respuestas pueden ser útiles: http: // stackoverflow.com/questions/73468/non-blocking-pthread-join – Corbin

Respuesta

1

cola Productor-consumidor. Haga que los hilos cola * ellos mismos, y por lo tanto sus resultados, (si corresponde), a la cola antes de que salgan. Espera en la cola.

Sin sondeo, sin latencia.

Con su diseño actual, tendría que unir() los hilos devueltos obtienen el valor y asegurarse de que se destruyan.

Tal vez en algún momento podría pasar a un subproceso de subprocesos real, donde los elementos de tareas están en cola a los subprocesos que nunca terminan (¿eliminando así la creación/finalización/destrucción de la secuencia de comandos)?

+0

re: hilo de rosca real ... tuve esta idea antes. Estoy trabajando en el marco Qt y he usado su pool/modelo futuro antes, pero no estoy seguro si voy a poder usar eso en nombre de la portabilidad de este código – Derek

+0

Terminé tratando de implementar algo así como esto - originalmente el hilo principal era simplemente poner a todos los trabajadores en una cola, pero lo volví a trabajar un poco para que los woekers se agregaran a una cola cuando terminaron, y luego lanzaron una señal de condición para dejar que otros saber quién es el hilo para sacar algo de esa cola y unirla. – Derek

4

Aquí es una aplicación portátil de pthread_timedjoin_np. Es un poco costoso, pero es una gota en el reemplazo completo:

struct args { 
    int joined; 
    pthread_t td; 
    pthread_mutex_t mtx; 
    pthread_cond_t cond; 
    void **res; 
}; 

static void *waiter(void *ap) 
{ 
    struct args *args = ap; 
    pthread_join(args->td, args->res); 
    pthread_mutex_lock(&args->mtx); 
    args->joined = 1; 
    pthread_mutex_unlock(&args->mtx); 
    pthread_cond_signal(&args->cond); 
    return 0; 
} 

int pthread_timedjoin_np(pthread_t td, void **res, struct timespec *ts) 
{ 
    pthread_t tmp; 
    int ret; 
    struct args args = { .td = td, .res = res }; 

    pthread_mutex_init(&args.mtx, 0); 
    pthread_cond_init(&args.cond, 0); 
    pthread_mutex_lock(&args.mtx); 

    ret = pthread_create(&tmp, 0, waiter, &args); 
    if (ret) goto done; 

    do ret = pthread_cond_timedwait(&args.cond, &args.mtx, ts); 
    while (!args.joined && ret != ETIMEDOUT); 

    pthread_mutex_unlock(&args.mtx); 

    pthread_cancel(tmp); 
    pthread_join(tmp, 0); 

    pthread_cond_destroy(&args.cond); 
    pthread_mutex_destroy(&args.mtx); 

    return args.joined ? 0 : ret; 
} 

Puede haber pequeños errores que no escribo esto en el lugar y no prueba, pero el concepto es el sonido.

+0

Antes de publicar, en realidad había ideado un plan similar al de Martins, si parece que no funciona bien, intentaré esto. – Derek

+0

La solución de Martin es más limpia desde el punto de vista de no tener gastos innecesarios y ser conceptualmente mejor. El mío es solo un reemplazo directo para la función no portátil que le permite corregir código no portátil sin rediseñar nada. –

0

solución con alarm.

pthread debe habilitar la cancelación, por lo que puede pasar por externo. (Incluso con pthread_timedjoin_np).

pthread_timedjoin_np vuelve con ETIMEOUT después del tiempo de espera.

  1. conjunto alarm, utilice alarm también puede dar señal "TIMEOUT".
  2. En controlador, solo pthread_cancel es. (solo timeout ejecutar esto).
  3. pthread_join en el hilo principal.
  4. restablecer alarm

escribo código de prueba aquí: github