Thread Pool code in Linux

Source: Internet
Author: User

// Thrmgr. h

# Ifndef _ thrmgr_h __
# DEFINE _ thrmgr_h __

# Include <sys/time. h>
# Include <pthread. h>

Typedef struct work_item_tag
{
Struct work_item_tag * next;
Void * data;
Struct timeval time_queued;
} Work_item_t;

Typedef struct work_queue_tag
{
Work_item_t * head;
Work_item_t * tail;
Int item_count;
} Work_queue_t;

Typedef Enum
{
Pool_invalid,
Pool_valid,
Pool_exit,
} Pool_state_t;

Typedef struct threadpool_tag
{
Pthread_mutex_t pool_mutex;
Pthread_cond_t pool_cond;
Pthread_attr_t pool_attr;

Pool_state_t state;
Int thr_max;
Int thr_alive;
Int thr_idle;
Int idle_timeout;

Void (* Handler) (void *);

Work_queue_t * queue;
} Threadpool_t;

Threadpool_t * thrmgr_new (INT max_threads, int idle_timeout, void (* Handler) (void *));
Void thrmgr_destroy (threadpool_t * threadpool );
Int thrmgr_dispatch (threadpool_t * threadpool, void * user_data );

# Endif

// Thrmgr. c
# Include "thrmgr. H"

# Include <stdlib. h>
# Include <memory. h>
# Include <errno. h>

# Define false (0)
# Define true (1)

Work_queue_t * work_queue_new ()
{
Work_queue_t * work_q;

Work_q = (work_queue_t *) malloc (sizeof (work_queue_t ));

Work_q-> head = work_q-> tail = NULL;
Work_q-> item_count = 0;
Return work_q;
}

Void work_queue_add (work_queue_t * work_q, void * Data)
{
Work_item_t * work_item;

If (! Work_q)
{
Return;
}
Work_item = (work_item_t *) malloc (sizeof (work_item_t ));
Work_item-> next = NULL;
Work_item-> DATA = data;
Gettimeofday (& (work_item-> time_queued), null );

If (work_q-> head = NULL)
{
Work_q-> head = work_q-> tail = work_item;
Work_q-> item_count = 1;
}
Else
{
Work_q-> tail-> next = work_item;
Work_q-> tail = work_item;
Work_q-> item_count ++;
}
Return;
}

Void * work_queue_pop (work_queue_t * work_q)
{
Work_item_t * work_item;
Void * data;

If (! Work_q |! Work_q-> head)
{
Return NULL;
}

Work_item = work_q-> head;
Data = work_item-> data;
Work_q-> head = work_item-> next;
If (work_q-> head = NULL)
{
Work_q-> tail = NULL;
}

Free (work_item );
Return data;
}

Void thrmgr_destroy (threadpool_t * threadpool)
{
If (! Threadpool | (threadpool-> state! = Pool_valid ))
{
Return;
}

If (pthread_mutex_lock (& threadpool-> pool_mutex )! = 0)
{
// Logg ("! Mutex lock failed/N ");
Exit (-1 );
}
Threadpool-> state = pool_exit;

/* Wait For threads to exit */
If (threadpool-> thr_alive> 0)
{
If (pthread_cond_broadcast (& (threadpool-> pool_cond ))! = 0)
{
Pthread_mutex_unlock (& threadpool-> pool_mutex );
Return;
}
}

While (threadpool-> thr_alive> 0)
{
If (pthread_cond_wait (& threadpool-> pool_cond, & threadpool-> pool_mutex )! = 0)
{
Pthread_mutex_unlock (& threadpool-> pool_mutex );
Return;
}
}

If (pthread_mutex_unlock (& threadpool-> pool_mutex )! = 0)
{
// Logg ("! Mutex unlock failed/N ");
Exit (-1 );
}

Pthread_mutex_destroy (& (threadpool-> pool_mutex ));
Pthread_cond_destroy (& (threadpool-> pool_cond ));
Pthread_attr_destroy (& (threadpool-> pool_attr ));
Free (threadpool );
Return;
}

Threadpool_t * thrmgr_new (INT max_threads, int idle_timeout, void (* Handler) (void *))
{
Threadpool_t * threadpool;

If (max_threads <= 0)
{
Return NULL;
}

Threadpool = (threadpool_t *) malloc (sizeof (threadpool_t ));

Threadpool-> queue = work_queue_new ();
If (! Threadpool-> Queue)
{
Free (threadpool );
Return NULL;
}

Threadpool-> thr_max = max_threads;
Threadpool-> thr_alive = 0;
Threadpool-> thr_idle = 0;
Threadpool-> idle_timeout = idle_timeout;
Threadpool-> handler = handler;

Pthread_mutex_init (& (threadpool-> pool_mutex), null );
If (pthread_cond_init (& (threadpool-> pool_cond), null )! = 0)
{
Free (threadpool );
Return NULL;
}

If (pthread_attr_init (& (threadpool-> pool_attr ))! = 0)
{
Free (threadpool );
Return NULL;
}

If (pthread_attr_setdetachstate (& (threadpool-> pool_attr), pthread_create_detached )! = 0)
{
Free (threadpool );
Return NULL;
}
Threadpool-> state = pool_valid;

Return threadpool;
}

Void * thrmgr_worker (void * Arg)
{
Threadpool_t * threadpool = (threadpool_t *) ARG;
Void * job_data;
Int retval, must_exit = false;
Struct timespec timeout;

/* Loop looking for work */
For (;;)
{
If (pthread_mutex_lock (& (threadpool-> pool_mutex ))! = 0)
{
/* Fatal error */
// Logg ("! Fatal: mutex lock failed/N ");
Exit (-2 );
}

Timeout. TV _sec = Time (null) + threadpool-> idle_timeout;
Timeout. TV _nsec = 0;
Threadpool-> thr_idle ++;
While (job_data = work_queue_pop (threadpool-> Queue) = NULL) & (threadpool-> state! = Pool_exit ))
{
// Sleep, awaiting wakeup,
Retval = pthread_cond_timedwait (& (threadpool-> pool_cond), & (threadpool-> pool_mutex), & timeout );
If (retval = etimedout)
{
Must_exit = true;
Break;
}
}

Threadpool-> thr_idle --;
If (threadpool-> state = pool_exit)
{
Must_exit = true;
}

If (pthread_mutex_unlock (& (threadpool-> pool_mutex ))! = 0)
{
/* Fatal error */
// Logg ("! Fatal: mutex unlock failed/N ");
Exit (-2 );
}

If (job_data)
{
Threadpool-> handler (job_data );
}
Else if (must_exit)
{
Break;
}
}

If (pthread_mutex_lock (& (threadpool-> pool_mutex ))! = 0)
{
/* Fatal error */
// Logg ("! Fatal: mutex lock failed/N ");
Exit (-2 );
}

Threadpool-> thr_alive --;
If (threadpool-> thr_alive = 0)
{
/* Signal that all threads are finished */
Pthread_cond_broadcast (& threadpool-> pool_cond );
}

If (pthread_mutex_unlock (& (threadpool-> pool_mutex ))! = 0)
{
/* Fatal error */
// Logg ("! Fatal: mutex unlock failed/N ");
Exit (-2 );
}

Return NULL;
}

Int thrmgr_dispatch (threadpool_t * threadpool, void * user_data)
{
Pthread_t thr_id;

If (! Threadpool)
{
Return false;
}

/* Lock the threadpool */
If (pthread_mutex_lock (& (threadpool-> pool_mutex ))! = 0)
{
// Logg ("! Mutex lock failed/N ");
Return false;
}

If (threadpool-> state! = Pool_valid)
{
If (pthread_mutex_unlock (& (threadpool-> pool_mutex ))! = 0)
{
// Logg ("! Mutex unlock failed/N ");
Return false;
}
Return false;
}

Work_queue_add (threadpool-> queue, user_data );

// Create a thread only when there is no thread idle and the number of threads currently generated is smaller than the maximum number of threads required
If (threadpool-> thr_idle = 0) & (threadpool-> thr_alive <threadpool-> thr_max ))
{
/* Start a new thread */
If (pthread_create (& thr_id, & (threadpool-> pool_attr), thrmgr_worker, threadpool )! = 0)
{
// Logg ("! Pthread_create failed/N ");
}
Else
{
Threadpool-> thr_alive ++;
}
}

/* Release the conditional signal. If there is a thread waiting for the signal, the thread runs */
Pthread_cond_signal (& (threadpool-> pool_cond ));

If (pthread_mutex_unlock (& (threadpool-> pool_mutex ))! = 0)
{
// Logg ("! Mutex unlock failed/N ");
Return false;
}

Return true;
}

/*
The following describes how to use a TCP server,

1. thrmgr_new

2, while (1)

{

Accept (......);

// Construct input parameters

Thrmgr_dispach (...);

}

Thrmgr_destory (...);

Int main ()
{
Threadpool_t * threadpool = thrmgr_new (5, 0, handle );
Thrmgr_dispatch (threadpool, (void *) 5 );
Thrmgr_dispatch (threadpool, (void *) 7 );
Thrmgr_destroy (threadpool );
}
*/

 

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.