/* Written in the previous words:
Today just "Kaiyuan", chose an article about the thread pool file with you to share, hope to learn from you to help, but also hope to work with you to learn!
Choose to register concurrent articles at this particular time is also some of my personal special significance, see my ID (West Tour Elementary school students. 45) just know, haha. Here is also very grateful to the blog Park staff, just send an application two minutes to agree.
*/
Recently because to write a similar to the QQ program, so think of the use of multithreading. If you want to use multithreading, why not write a thread pool? So the internet search for multi-threaded code, found that most are not very perfect, or some small bugs. So, here is a complete, after my multi-test, first affixed to a thread pool of the simple implementation process (fixed-size thread pool), later and network programming after a few days will be posted again. Here's a quote from Linux: "
Talk is cheap show me the Code
”。 So most of my blog will be put code for everyone, thank you.
The first thing you have to mention is the benefits of the thread pool:
Simply put, if you call a thread divided into:
T1 Creating threads
T2 finish the Job
T3 Destroying threads
So if we have 100 jobs to complete, the total time t=100* (T1+T2+T3). But if we apply for a fixed-size thread pool of 10 threads in advance, the total time to complete the job is to request 10 threads and destroy 10 threads and 100 jobs, and T=10*T1+100*T2+10*T3. So the biggest advantage of thread pooling is that it saves the time of thread application and destruction!
The following is a specific code implementation:
/*************************************************************************
> File name:tpool.h
> AUTHOR:&NBSP
> mail:
> Created time:2015 April 01 Wednesday 17:34 00 sec.
******************************* *****************************************/
#ifndef thread_pool_h__
#define Thread_pool_h__
#include <pthread.h>
/* The list of tasks to perform */
typedef struct TPOOL_WORK {
void* (*routine) (int); /* Task function */
int arg; /* Parameters for incoming task function */
struct Tpool_work *next;
}tpool_work_t;
typedef struct TPOOL {
int shutdown; /* thread pool is destroyed */
int max_thr_num; /* Maximum number of threads */
pthread_t *thr_id; /* Thread ID Array */
tpool_work_t *queue_head; /* Line Threads */
pthread_mutex_t Queue_lock;
pthread_cond_t Queue_ready;
}tpool_t;
/*
* @brief Create a thread pool
* @param max_thr_num Maximum number of threads
* @return 0: Success Other: Failure
*/
Int
tpool_create (int max_thr_num);
/*
* @brief Destroy thread pool
*/
void
Tpool_destroy ();
/*
* @brief adding tasks to the thread pool
* @param routine task function pointer
* @param arg task function parameter
* @return 0: Success Other: Failure
*/
Int
Tpool_add_work (void* (*routine) (int), int arg);
#endif
/*************************************************************************
> File NAME:FUNC.C
> Author:
> Mail:
> Created time:2015 April 01 Wednesday 17:35 56 seconds
************************************************************************/
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <stdio.h>
#include "tpool.h"
static tpool_t *tpool = NULL;
void
Print_work (tpool_work_t *head)//Output task queue current work
{
tpool_work_t *work= Head;
printf (\ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ \ n ")
while (work) {
printf ("%d", work->arg);
Work = work->next;
}
printf ("\ n");
}
/* worker thread function, remove task from task List and execute */
Static void*
Thread_routine (void *arg)
{
tpool_work_t *work; Task linked List
while (1) {
/* If the thread pool is not destroyed and there are no tasks to execute, wait */
Pthread_mutex_lock (&tpool->queue_lock); Lock the thread pool
while (!tpool->queue_head &&!tpool->shutdown) {
Pthread_cond_wait (&tpool->queue_ready, &tpool->queue_lock);
}
if (Tpool->shutdown) {//0 not logged off
Pthread_mutex_unlock (&tpool->queue_lock);
Pthread_exit (NULL);
}
Sleep (3);
Print_work (Tpool->queue_head);
One job to remove the task link header
Work = tpool->queue_head;
Tpool->queue_head = tpool->queue_head->next;
Pthread_mutex_unlock (&tpool->queue_lock);
Work->routine (WORK->ARG);
Free (work);
}
return NULL;
}
/*
* Create thread pool
*/
Int
tpool_create (int max_thr_num)
{
int i;
Tpool = calloc (1, sizeof (tpool_t)); Thread Pool Tpool
if (!tpool) {
printf ("%s:calloc failed\n", __function__);
Exit (1);
}
/* Initialize */
Tpool->max_thr_num = Max_thr_num; Initialize the maximum number of thread pools
Tpool->shutdown = 0; Thread pool logoff set to 0 no note
Tpool->queue_head = NULL; Thread pool Linked list
if (Pthread_mutex_init (&tpool->queue_lock, NULL)!=0) {//initialization of the thread lock
printf ("%s:pthread_mutex_init failed, errno:%d, error:%s\n",
__function__, errno, Strerror (errno));
Exit (1);
}
if (Pthread_cond_init (&tpool->queue_ready, NULL)!=0) {//Initialize condition variable
printf ("%s:pthread_cond_init failed, errno:%d, error:%s\n",
__function__, errno, Strerror (errno));
Exit (1);
}
/* Create worker thread */
tpool->thr_id = calloc (max_thr_num, sizeof (pthread_t));//application thread ID array
if (!tpool->thr_id) {
printf ("%s:calloc failed\n", __function__);
Exit (1);
}
for (i = 0; i < Max_thr_num; ++i) {
if (Pthread_create (&tpool->thr_id[i], NULL, thread_routine, NULL)! = 0) {
printf ("%s:pthread_create failed, errno:%d, error:%s\n", __function__,
errno, Strerror (errno));
Exit (1);
}
}
return 0;
}
/* Destroy thread pool */
void
Tpool_destroy ()
{
int i;
tpool_work_t *member;
if (Tpool->shutdown) {
Return
}
Tpool->shutdown = 1;
/* Notify all waiting threads */
Pthread_mutex_lock (&tpool->queue_lock);
Pthread_cond_broadcast (&tpool->queue_ready);
Pthread_mutex_unlock (&tpool->queue_lock);
for (i = 0; i < tpool->max_thr_num; ++i) {
Pthread_join (Tpool->thr_id[i], NULL);
}
Free (tpool->thr_id);
while (Tpool->queue_head) {
member = tpool->queue_head;
Tpool->queue_head = tpool->queue_head->next;
Free (member);
}
Pthread_mutex_destroy (&tpool->queue_lock);
Pthread_cond_destroy (&tpool->queue_ready);
Free (tpool);
}
/* Add tasks to the thread pool */
Int
Tpool_add_work (void* (*routine) (int), int arg)
{
tpool_work_t *work, *member;
if (!routine) {
printf ("%s:invalid argument\n", __function__);
return-1;
}
Work = malloc (sizeof (tpool_work_t)); Apply for a task node.
if (!work) {//Application failed
printf ("%s:malloc failed\n", __function__);
return-1;
}
Work->routine = routine; The thread execution function is set to the parameter passed in main
Work->arg = arg; The parameters of the thread execution function are set to the arguments passed in main
Work->next = NULL;
Pthread_mutex_lock (&tpool->queue_lock); Locking Line Cheng
member = tpool->queue_head;
if (!member) {//finds the last node in the thread-linked list, and the work is placed at the end of the line threads
Tpool->queue_head = Work;
} else {
while (Member->next) {
member = member->next;
}
Member->next = Work;
}
/* Notify worker thread that a new task is added */
Pthread_cond_signal (&tpool->queue_ready);
Pthread_mutex_unlock (&tpool->queue_lock);
return 0;
}
void *func (int arg)
{
printf ("Thread%d ThreadID is:%d\n", ARG, (int) pthread_self ());
Print_work (Tpool->queue_head);
Sleep (3);
return NULL;
}
Int
Main (int arg, char **argv)
{
if (Tpool_create (5)! = 0) {
printf ("Tpool_create failed\n");
Exit (1);
}
int i;
for (i = 0; i < ++i) {
Tpool_add_work (func, I);
Usleep (1);
}
Sleep (10); If sleep is not enough or the time is too short, note that the main thread may be completed before the other thread finishes causing some jobs to not complete
Tpool_destroy ();
return 0;
}
Simple multithreaded programming under Linux--the implementation of thread pool