Example of generalized thread pool in C language with signal handling.
rev 2: Completely revised the code of the library.
Now there is a queue of jobs, a thread is awakened when a new job is available, following the classic mechanism of producer / consumer.
You can set: the thread pool size, its signal mask and the size of the job queue, calling the poolInit function that returns a new pool. If the signal mask is null then the signal mask shall be inherited from the creating thread.
The function poolDispatcher gets three arguments the pointer to the pool; a void pointer to function (start_routine), with a single argument void arg. (very similar to pthread_create). The poolDispather when executed creates a new job that is inserted into the queue of jobs.
If you send too many jobs to the pool and the queue fills up, the poolDispatcher reject the new job and returns the error code “-5” (to avoid DOS attacks).
The function poolDestroy, puts the pool in termination state, (the pool is no longer available to run new job), it waits for all active and pending jobs to finish; execute the join of the threads; free resources and exit.
doxygen docomuntation and source code (license GPLv2)
Esempio di pool di thread in linguaggio C generalizzato con gestione dei segnali.
E’ possibile passare a questa libreria un proprio puntatore a funzione.
La funzione verrà eseguita dal primo thread disponibile del pool di threads.
E’ facile notare come la funzione addjob esegue, nel caso in cui tutti i threads siano impegnati, attesa attiva.
La soluzione è presto detta, implementare una lista di jobs, oppure (per chi non ha voglia) aumentare opportunamente la dimensione del pool threads.
[update]
Rivisto completamente il codice della libreria.
Adesso esiste una lista di job; un thread del pool viene risvegliato quando un nuovo job è disponibile, seguendo il classico meccanismo di produttore/consumatore.
La dimensione massima della coda dei job è settabile in fase di creazione del pool.
Se si inviano troppi job al pool e la coda si riempie, la poolDispatcher rifiuterà il nuovo job ritornando il codice di errore “-5” (evitiamo attacchi di DOS).
La funzione poolDestroy, mette il pool in fase di terminazione, (ovvero il pool non è più disponibile ad eseguire nuovi job), aspetta che tutti i job attivi e pendenti terminino; esegue la join dei threads; libera le risorse ed esce.
[update-end]
Una volta terminato il job, il thread viene reso automaticamente disponibile per un nuovo job.
La dimensione del pool e la maschera dei segnali per i threads sono passate in fase di inizializzazione del pool stesso.
E’ possibile creare infiniti pool di threads, dato che ogni struttura dati viene creata dinamicamente in fase di inizializzazione del pool stesso. La maschera dei segnali è invece opzionale.
Per commenti e info più dettagliate sul codice: documentazione html (doxygen).
E per scaricare il codice sorgente: codice sorgente (in licenza gpl v2).