Linux第三次实验:Linux下的线程及线程池实验

前言

为了帮助同学们完成痛苦的实验课程设计,本作者将其作出的实验结果及代码贴至CSDN中,供同学们学习参考。如有不足或描述不完善之处,敬请各位指出,欢迎各位的斧正!

一、实验目的

  1. 理解Linux的线程原理。
  2. 掌握和使用线程函数实现线程的操作。
  3. 掌握和使用互斥锁和信号量实现线程同步。
  4. 掌握线程池。

二、实验工具与设备

装有Linux系统的计算机

三、实验预备知识

线程可以提高应用程序在多核环境下处理诸如文件I/O或者socket I/O等会产生堵塞的情况的表现性能。在Unix系统中,一个进程包含很多东西,包括可执行程序以及一大堆的诸如文件描述符地址空间等资源。在很多情况下,完成相关任务的不同代码间需要交换数据。如果采用多进程的方式,那么通信就需要在用户空间和内核空间进行频繁的切换,开销很大。但是如果使用多线程的方式,因为可以使用共享的全局变量,所以线程间的通信(数据交换)变得非常高效。
头文件:#include <pthread.h>
需要的编译条件:-pthread
线程结构体pthread_attr_t中记录线程的信息。

typedef struct
{
    int               detachstate;   线程的分离状态
    int               schedpolicy;   线程调度策略
    structsched_param schedparam;    线程的调度参数
    int               inheritsched;  线程的继承性
    int               scope;         线程的作用域
    size_t            guardsize;     线程栈末尾的警戒缓冲区大小
    int               stackaddr_set; 
    void*             stackaddr;     线程栈的位置
    size_t            stacksize;     线程栈的大小
}pthread_attr_t;

线程相关的接口函数:
对线程属性初始化/去除初始化

int pthread_attr_init(pthread_attr_t *attr); int pthread_attr_destroy(pthread_attr_t *attr);

创建线程

int pthread_create(pthread_t *thread, const pthread_attr_t *attr, void *(*start_routine) (void *), void *arg);

向线程发送终止信号

int pthread_cancel(pthread_t thread);

使线程进入分离态

int pthread_detach(pthread_t thread);

比较两个线程的标识符

int pthread_equal(pthread_t t1, pthread_t t2);

使线程退出

void pthread_exit(void *retval);

通过结构体初始化,用于明确指定线程属性

int pthread_getattr_np(pthread_t thread, pthread_attr_t *attr);

等待指定线程的结束

int pthread_join(pthread_t thread, void **retval);

返回线程当前的描述符

pthread_t pthread_self(void);

四、实验内容和步骤

  1. 创建线程。
#include <stdio.h>
#include <pthread.h>
 void *mythread1(void)
{
	int i;
	for(i = 0; i < 10; i++)
	{
		printf("This is the pthread1,i=%d\n",i);
		sleep(1);
	}
}
void *mythread2(void)
{
	int i;
	for(i = 0; i < 10; i++)
	{
		printf("This is the pthread1,i=%d\n",i );
		sleep(1);
	}
}
int main(int argc, const char *argv[])
{
	int i = 0;
	int ret = 0;
	pthread_t id1,id2;
	ret = pthread_create(&id1, NULL, (void *)mythread1,NULL);
	if(ret)
	{
		printf("Create pthread error!\n");
		return 1;
	}
	ret = pthread_create(&id2, NULL, (void *)mythread2,NULL);
	if(ret)
	{
		printf("Create pthread error!\n");
		return 1;
	}
	pthread_join(id1,NULL);
	pthread_join(id2,NULL);
 	return 0;
}

执行以下命令编译程序并执行:gcc -o Createthread Createthread.c -lpthread

  1. 创建两个线程实现对一个数的递加。
#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define MAX 20
pthread_t thread[2];  //两个线程
pthread_mutex_t mut;
int number=0;
int i;
void *thread1()
{
        printf ("thread1 : this is the thread1\n");
        for (i = 0; i < MAX; i++)   //模拟线程执行时间
        {
                printf("thread1 : number = %d\n",number);
                pthread_mutex_lock(&mut);
                        number++;
                pthread_mutex_unlock(&mut);
                sleep(2);
        }
        printf("thread1 :主函数在等我完成任务吗?\n");
        pthread_exit(NULL);
}
void *thread2()
{
        printf(""thread2 : this is the thread2\n");
        for (i = 0; i < MAX; i++)
        {
                printf("thread2 : number = %d\n",number);
                pthread_mutex_lock(&mut);
                        number++;
                pthread_mutex_unlock(&mut);
                sleep(3);
        }
        printf("thread2 :主函数在等我完成任务吗?\n");
        pthread_exit(NULL);
}
void thread_create(void)   //创建两个线程
{
        int temp;
        memset(&thread, 0, sizeof(thread));          //comment1
        /*创建线程*/
        if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)  //comment2     
                printf("线程1创建失败\n");
        else
                printf("线程1被创建\n");
        if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)  //comment3
                printf("线程2创建失败\n");
        else
                printf("线程2被创建\n");
}
void thread_wait(void)
{
        /*等待线程结束*/
        if(thread[0] !=0)
           {             //comment4    
                pthread_join(thread[0],NULL);
                printf("线程1已经结束\n");
          }
        if(thread[1] !=0) 
           {  
                //comment5
               pthread_join(thread[1],NULL);
                printf("线程2已经结束\n");
         }
}
int main()
{
        /*用默认属性初始化互斥锁*/
        pthread_mutex_init(&mut,NULL);
        printf("创建线程\n");
        thread_create();
        printf("等待线程完成任务\n");
        thread_wait();
        return 0;
}

通过以下命令编译:gcc -lpthread -o thread_example thread_example.c

  1. 线程同步
    未同步示例程序:
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define LEN 100000
int num = 0;
void* thread_func(void* arg) {
    for (int i = 0; i< LEN; ++i) {
        num += 1;
    }
    return NULL;
}
int main() {
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, (void*)thread_func, NULL);
    pthread_create(&tid2, NULL, (void*)thread_func, NULL);
    char* rev = NULL;
    pthread_join(tid1, (void *)&rev);
    pthread_join(tid2, (void *)&rev);
    printf("correct result=%d, wrong result=%d.\n", 2*LEN, num);
    return 0;
}

运行结果:correct result=200000, wrong result=106860.
通过互斥解决同步问题的程序:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define LEN 100000
int num = 0;
void* thread_func(void* arg) {
    pthread_mutex_t* p_mutex = (pthread_mutex_t*)arg;
    for (int i = 0; i< LEN; ++i) {
        pthread_mutex_lock(p_mutex);
        num += 1;
        pthread_mutex_unlock(p_mutex);
    }
    return NULL;
}
int main() {
    pthread_mutex_t m_mutex;
    pthread_mutex_init(&m_mutex, NULL);
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, (void*)thread_func, (void*)&m_mutex);
    pthread_create(&tid2, NULL, (void*)thread_func, (void*)&m_mutex);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_mutex_destroy(&m_mutex);
    printf("correct result=%d, result=%d.\n", 2*LEN, num);
    return 0;
}

运行结果:correct result=200000, result=200000.

  1. 编写信号量使用程序
#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<string.h>
#include<semaphore.h>
#define NUM 5
int queue[NUM];
sem_t psem, csem; 
void producer(void* arg) {
    int pos = 0;
    int num, count = 0;
    for (int i=0; i<12; ++i) {
        num = rand() % 100;
        count += num;
        sem_wait(&psem);
        queue[pos] = num;
        sem_post(&csem);
        printf("producer: %d\n", num); 
        pos = (pos+1) % NUM;
        sleep(rand()%2);
    }
    printf("producer count=%d\n", count);
}
void consumer(void* arg){
    int pos = 0;
    int num, count = 0;
    for (int i=0; i<12; ++i) {
        sem_wait(&csem);
        num = queue[pos];
        sem_post(&psem);
        printf("consumer: %d\n", num);
        count += num;
        pos = (pos+1) % NUM;
        sleep(rand()%3);
    }
    printf("consumer count=%d\n", count);    
} 
int main() {
    sem_init(&psem, 0, NUM);
    sem_init(&csem, 0, 0);
    pthread_t tid[2];
    pthread_create(&tid[0], NULL, (void*)producer, NULL);
    pthread_create(&tid[1], NULL, (void*)consumer, NULL);
    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);
    sem_destroy(&psem);
    sem_destroy(&csem);
    return 0;
}
  1. 编写线程池程序
    1.理解并运行以下线程实现
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
typedef struct condition
{
	pthread_mutex_t pmutex;
	pthread_cond_t pcond;
}condition_t;
typedef struct task
{
	void *(*run)(void *arg);
	void *arg;
	struct task *next;
}task_t;
typedef struct threadpool
{
	condition_t ready;
	task_t *first;
	task_t *last;
	int counter;
	int idle;
	int max_threads;
	int quit;
}threadpool_t;
int condition_init(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_init(&cond->pmutex,NULL)))//返回0代表初始化成功
		return status;
	if((status = pthread_cond_init(&cond->pcond,NULL)))
		return status;
	return 0;
}
int condition_lock(condition_t *cond)
{
	return pthread_mutex_lock(&cond -> pmutex);
}
int condition_unlock(condition_t *cond)
{
	return pthread_mutex_unlock(&cond -> pmutex);
}
int condition_wait(condition_t *cond)
{
	return pthread_cond_wait(&cond -> pcond,&cond -> pmutex);
}
int condition_timewait(condition_t *cond,const struct timespec *abstime)
{
	return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);
}
int condition_signal(condition_t *cond)
{
	return pthread_cond_signal(&cond->pcond);
}
int condition_broadcast(condition_t *cond)
{
	return pthread_cond_broadcast(&cond -> pcond);
}
int condition_destory(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_destroy(&cond -> pmutex)))
		return status;
	if((status = pthread_cond_destroy(&cond -> pcond)))
		return status;
	return 0;
}
void *thread_routine(void *arg)
{
	struct timespec abstime;
	int timeout;
	printf("thread 0x%0x is starting\n",(int)pthread_self());
	threadpool_t *pool = (threadpool_t *)arg;
	while(1)
	{
		timeout = 0;
		condition_lock(&pool -> ready);
		pool -> idle++;
		//等待队列有任务到来或者线程池销毁的通知
		while(pool -> first == NULL && !pool -> quit)
		{
			printf("thread 0x%0x is waiting\n",(int)pthread_self());
			clock_gettime(CLOCK_REALTIME,&abstime);
			abstime.tv_sec += 2;
			int status=condition_timewait(&pool -> ready,&abstime);
			if(status == ETIMEDOUT)
			{
				printf("thread 0x%0x is wait timed out\n",(int)pthread_self());
				timeout = 1;
				break;
			}
		}
		//等到到条件,处于工作状态
		pool -> idle--;
	    if(pool -> first != NULL)
		{
			task_t *t = pool -> first;
			pool -> first = t -> next;
			//需要先解锁,以便添加新任务。其他消费者线程能够进入等待任务。
			condition_unlock(&pool -> ready);
			t -> run(t->arg);
			free(t);
			condition_lock(&pool -> ready);
		}
		//等待线程池销毁的通知
		if(pool -> quit && pool ->first == NULL)
		{
			pool -> counter--;
			if(pool->counter == 0)
			{
				condition_signal(&pool -> ready);
			}
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}
		if(timeout &&pool -> first ==NULL)
		{
			pool -> counter--;
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}
		condition_unlock(&pool -> ready);
	}
	printf("thread 0x%0x is exiting\n",(int)pthread_self());
	return NULL;
}
//初始化
void threadpool_init(threadpool_t *pool, int threads)
{
	condition_init(&pool -> ready);
	pool -> first = NULL;
	pool -> last = NULL;
	pool -> counter = 0;
	pool -> idle = 0;
	pool -> max_threads = threads;
	pool -> quit = 0;
}
//加任务
void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg),void *arg)
{
	task_t *newstask = (task_t *)malloc(sizeof(task_t));
	newstask->run = run;
	newstask->arg = arg;
	newstask -> next = NULL;
	
	condition_lock(&pool -> ready);
	//将任务添加到对列中
	if(pool -> first ==NULL)
	{
		pool -> first = newstask;
	}
	else
		pool -> last -> next = newstask;
	pool -> last = newstask;
	//如果有等待线程,则唤醒其中一个
	if(pool -> idle > 0)
	{
		condition_signal(&pool -> ready);
	}
	else if(pool -> counter < pool -> max_threads)
	{
		pthread_t tid;
		pthread_create(&tid,NULL,thread_routine,pool);
		pool -> counter++;
	}
	condition_unlock(&pool -> ready);
}
//销毁线程池
void  threadpool_destory(threadpool_t *pool)
{
	if(pool -> quit)
	{
		return;
	}
	condition_lock(&pool -> ready);
	pool->quit = 1;
	if(pool -> counter > 0)
	{
		if(pool -> idle > 0)
			condition_broadcast(&pool->ready);
		while(pool -> counter > 0)
		{
			condition_wait(&pool->ready);
		}
	}
	condition_unlock(&pool->ready);
	condition_destory(&pool -> ready);
}
void *mytask(void *arg)
{
	printf("thread 0x%0x is working on task %d\n",(int)pthread_self(),*(int*)arg);
	sleep(1);
	free(arg);
	return NULL;
}
int main()
{
	threadpool_t pool;
	threadpool_init(&pool,3);
	
	int i ;
	for(i = 0; i < 10; i++)
	{
		int *arg = (int *)malloc(sizeof(int));
		*arg = i;
		threadpool_add_task(&pool,mytask,arg);
	}
	
	sleep(15);
	threadpool_destory(&pool);
	return 0;
}

编译运行:gcc Threadpool.c -o Threadpool -lpthread -lrt
2.参考https://www.cnblogs.com/jiangzhaowei/p/10383049.html编写复杂的线程池;
3.改造属于自己的线程池代码。

五、实验代码及步骤截图

3-1.c:

#include <stdio.h>
#include <pthread.h>
 void *mythread1(void)
{
	int i;
	for(i = 0; i < 10; i++)
	{
		printf("This is the pthread1,i=%d\n",i);
		sleep(1);
	}
}
void *mythread2(void)
{
	int i;
	for(i = 0; i < 10; i++)
	{
		printf("This is the pthread2,i=%d\n",i );
		sleep(1);
	}
}
int main(int argc, const char *argv[])
{
	int i = 0;
	int ret = 0;
	pthread_t id1,id2;
	ret = pthread_create(&id1, NULL, (void *)mythread1,NULL);
	if(ret)
	{
		printf("Create pthread error!\n");
		return 1;
	}
	ret = pthread_create(&id2, NULL, (void *)mythread2,NULL);
	if(ret)
	{
		printf("Create pthread error!\n");
		return 1;
	}
	pthread_join(id1,NULL);
	pthread_join(id2,NULL);
 	return 0;
}

实验3-1运行截图如下:
在这里插入图片描述
3-2.c:

#include <pthread.h>
#include <stdio.h>
#include <sys/time.h>
#include <string.h>
#define MAX 20
pthread_t thread[2];  //两个线程
pthread_mutex_t mut;
int number=0;
int i;
void *thread1()
{
	printf ("thread1 : this is the thread1\n");
	for (i = 0; i < MAX; i++)   //模拟线程执行时间
	{
		printf("thread1 : number = %d\n",number);
		pthread_mutex_lock(&mut);
		number++;
		pthread_mutex_unlock(&mut);
		sleep(2);
        }
	printf("thread1 :主函数在等我完成任务吗?\n");
	pthread_exit(NULL);
}
void *thread2()
{
	printf("thread2 : this is the thread2\n");
	for (i = 0; i < MAX; i++)
	{
		printf("thread2 : number = %d\n",number);
		pthread_mutex_lock(&mut);
		number++;
		pthread_mutex_unlock(&mut);
		sleep(3);
	}
	printf("thread2 :主函数在等我完成任务吗?\n");
	pthread_exit(NULL);
}
void thread_create(void)   //创建两个线程
{
	int temp;
	memset(&thread, 0, sizeof(thread));          //comment1
        /*创建线程*/
	if((temp = pthread_create(&thread[0], NULL, thread1, NULL)) != 0)  //comment2     
		printf("线程1创建失败\n");
	else
		printf("线程1被创建\n");
	if((temp = pthread_create(&thread[1], NULL, thread2, NULL)) != 0)  //comment3
		printf("线程2创建失败\n");
	else
		printf("线程2被创建\n");
}
void thread_wait(void)
{
        /*等待线程结束*/
	if(thread[0] !=0)
	{             //comment4    
		pthread_join(thread[0],NULL);
		printf("线程1已经结束\n");
	}
	if(thread[1] !=0) 
	{  
		//comment5
		pthread_join(thread[1],NULL);
		printf("线程2已经结束\n");
	}
}
int main()
{
        /*用默认属性初始化互斥锁*/
	pthread_mutex_init(&mut,NULL);
	printf("创建线程\n");
	thread_create();
	printf("等待线程完成任务\n");
	thread_wait();
	return 0;
}

实验3-2运行截图如下:
在这里插入图片描述

3-3.c:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define LEN 100000
int num = 0;
void* thread_func(void* arg)
{
	int i;
	for (i=0; i<LEN; ++i)
	{
		num += 1;
	}
	return NULL;
}
int main() 
{
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, (void*)thread_func, NULL);
    pthread_create(&tid2, NULL, (void*)thread_func, NULL);
    char* rev = NULL;
    pthread_join(tid1, (void *)&rev);
    pthread_join(tid2, (void *)&rev);
    printf("correct result=%d, wrong result=%d.\n", 2*LEN, num);
    return 0;
}

3-3.c运行截图如下:
在这里插入图片描述

3-3-1.c:

#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
#define LEN 100000
int num = 0;
void* thread_func(void* arg)
{
	pthread_mutex_t* p_mutex = (pthread_mutex_t*)arg;
	int i;
	for (i = 0; i< LEN; ++i)
	{
		pthread_mutex_lock(p_mutex);
		num += 1;
		pthread_mutex_unlock(p_mutex);
	}
	return NULL;
}
int main()
{
    pthread_mutex_t m_mutex;
    pthread_mutex_init(&m_mutex, NULL);
    pthread_t tid1, tid2;
    pthread_create(&tid1, NULL, (void*)thread_func, (void*)&m_mutex);
    pthread_create(&tid2, NULL, (void*)thread_func, (void*)&m_mutex);
    pthread_join(tid1, NULL);
    pthread_join(tid2, NULL);
    pthread_mutex_destroy(&m_mutex);
    printf("correct result=%d, result=%d.\n", 2*LEN, num);
    return 0;
}

3-3-1.c运行截图如下:
在这里插入图片描述

3-4.c:

#include<sys/types.h>
#include<unistd.h>
#include<stdlib.h>
#include<stdio.h>
#include<pthread.h>
#include<errno.h>
#include<string.h>
#include<semaphore.h>
#define NUM 5
int queue[NUM];
sem_t psem, csem; 
void producer(void* arg) {
    int pos = 0;
    int num, count = 0;
	int i;
    for (i=0; i<12; ++i) {
        num = rand() % 100;
        count += num;
        sem_wait(&psem);
        queue[pos] = num;
        sem_post(&csem);
        printf("producer: %d\n", num); 
        pos = (pos+1) % NUM;
        sleep(rand()%2);
    }
    printf("producer count=%d\n", count);
}
void consumer(void* arg){
    int pos = 0;
    int num, count = 0;
	int i;
    for (i=0; i<12; ++i) {
        sem_wait(&csem);
        num = queue[pos];
        sem_post(&psem);
        printf("consumer: %d\n", num);
        count += num;
        pos = (pos+1) % NUM;
        sleep(rand()%3);
	}
    printf("consumer count=%d\n", count);    
} 
int main() {
    sem_init(&psem, 0, NUM);
    sem_init(&csem, 0, 0);
    pthread_t tid[2];
    pthread_create(&tid[0], NULL, (void*)producer, NULL);
    pthread_create(&tid[1], NULL, (void*)consumer, NULL);
    pthread_join(tid[0], NULL);
    pthread_join(tid[1], NULL);
    sem_destroy(&psem);
    sem_destroy(&csem);
    return 0;
}

3-4.c运行截图如下:
在这里插入图片描述
3-5.c:

#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <time.h>
#include <pthread.h>
typedef struct condition
{
	pthread_mutex_t pmutex;
	pthread_cond_t pcond;
}condition_t;
typedef struct task
{
	void *(*run)(void *arg);
	void *arg;
	struct task *next;
}task_t;
typedef struct threadpool
{
	condition_t ready;
	task_t *first;
	task_t *last;
	int counter;
	int idle;
	int max_threads;
	int quit;
}threadpool_t;
int condition_init(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_init(&cond->pmutex,NULL)))//返回0代表初始化成功
		return status;
	if((status = pthread_cond_init(&cond->pcond,NULL)))
		return status;
	return 0;
}
int condition_lock(condition_t *cond)
{
	return pthread_mutex_lock(&cond -> pmutex);
}
int condition_unlock(condition_t *cond)
{
	return pthread_mutex_unlock(&cond -> pmutex);
}
int condition_wait(condition_t *cond)
{
	return pthread_cond_wait(&cond -> pcond,&cond -> pmutex);
}
int condition_timewait(condition_t *cond,const struct timespec *abstime)
{
	return pthread_cond_timedwait(&cond->pcond,&cond->pmutex,abstime);
}
int condition_signal(condition_t *cond)
{
	return pthread_cond_signal(&cond->pcond);
}
int condition_broadcast(condition_t *cond)
{
	return pthread_cond_broadcast(&cond -> pcond);
}
int condition_destory(condition_t *cond)
{
	int status;
	if((status = pthread_mutex_destroy(&cond -> pmutex)))
		return status;
	if((status = pthread_cond_destroy(&cond -> pcond)))
		return status;
	return 0;
}
void *thread_routine(void *arg)
{
	struct timespec abstime;
	int timeout;
	printf("thread 0x%0x is starting\n",(int)pthread_self());
	threadpool_t *pool = (threadpool_t *)arg;
	while(1)
	{
		timeout = 0;
		condition_lock(&pool -> ready);
		pool -> idle++;
		//等待队列有任务到来或者线程池销毁的通知
		while(pool -> first == NULL && !pool -> quit)
		{
			printf("thread 0x%0x is waiting\n",(int)pthread_self());
			clock_gettime(CLOCK_REALTIME,&abstime);
			abstime.tv_sec += 2;
			int status=condition_timewait(&pool -> ready,&abstime);
			if(status == ETIMEDOUT)
			{
				printf("thread 0x%0x is wait timed out\n",(int)pthread_self());
				timeout = 1;
				break;
			}
		}
		//等到到条件,处于工作状态
		pool -> idle--;
	    if(pool -> first != NULL)
		{
			task_t *t = pool -> first;
			pool -> first = t -> next;
			//需要先解锁,以便添加新任务。其他消费者线程能够进入等待任务。
			condition_unlock(&pool -> ready);
			t -> run(t->arg);
			free(t);
			condition_lock(&pool -> ready);
		}
		//等待线程池销毁的通知
		if(pool -> quit && pool ->first == NULL)
		{
			pool -> counter--;
			if(pool->counter == 0)
			{
				condition_signal(&pool -> ready);
			}
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}
		if(timeout &&pool -> first ==NULL)
		{
			pool -> counter--;
			condition_unlock(&pool->ready);
			//跳出循环之前要记得解锁
			break;
		}
		condition_unlock(&pool -> ready);
	}
	printf("thread 0x%0x is exiting\n",(int)pthread_self());
	return NULL;
}
//初始化
void threadpool_init(threadpool_t *pool, int threads)
{
	condition_init(&pool -> ready);
	pool -> first = NULL;
	pool -> last = NULL;
	pool -> counter = 0;
	pool -> idle = 0;
	pool -> max_threads = threads;
	pool -> quit = 0;
}
//加任务
void threadpool_add_task(threadpool_t *pool, void *(*run)(void *arg),void *arg)
{
	task_t *newstask = (task_t *)malloc(sizeof(task_t));
	newstask->run = run;
	newstask->arg = arg;
	newstask -> next = NULL;
	
	condition_lock(&pool -> ready);
	//将任务添加到对列中
	if(pool -> first ==NULL)
	{
		pool -> first = newstask;
	}
	else
		pool -> last -> next = newstask;
	pool -> last = newstask;
	//如果有等待线程,则唤醒其中一个
	if(pool -> idle > 0)
	{
		condition_signal(&pool -> ready);
	}
	else if(pool -> counter < pool -> max_threads)
	{
		pthread_t tid;
		pthread_create(&tid,NULL,thread_routine,pool);
		pool -> counter++;
	}
	condition_unlock(&pool -> ready);
}
//销毁线程池
void  threadpool_destory(threadpool_t *pool)
{
	if(pool -> quit)
	{
		return;
	}
	condition_lock(&pool -> ready);
	pool->quit = 1;
	if(pool -> counter > 0)
	{
		if(pool -> idle > 0)
			condition_broadcast(&pool->ready);
		while(pool -> counter > 0)
		{
			condition_wait(&pool->ready);
		}
	}
	condition_unlock(&pool->ready);
	condition_destory(&pool -> ready);
}
void *mytask(void *arg)
{
	printf("thread 0x%0x is working on task %d\n",(int)pthread_self(),*(int*)arg);
	sleep(1);
	free(arg);
	return NULL;
}
int main()
{
	threadpool_t pool;
	threadpool_init(&pool,3);
	int i ;
	for(i = 0; i < 10; i++)
	{
		int *arg = (int *)malloc(sizeof(int));
		*arg = i;
		threadpool_add_task(&pool,mytask,arg);
	}
	
	sleep(15);
	threadpool_destory(&pool);
	return 0;
}

3-5.c运行截图如下:
在这里插入图片描述
2.参考https://www.cnblogs.com/jiangzhaowei/p/10383049.html编写复杂的线程池;
Main.c:

#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <pthread.h> 
#include <assert.h> 
#include <string.h>
#include "lib_thread_pool.h"
static void* thread_1(void* arg);
static void* thread_2(void* arg);
static void* thread_3(void* arg);
static void DisplayPoolStatus(CThread_pool_t* pPool);
int nKillThread = 0;
int main()
{
	CThread_pool_t* pThreadPool = NULL;
	pThreadPool = ThreadPoolConstruct(2, 1);
	int nNumInput = 5;
	char LogInput[] = "OK!";
	DisplayPoolStatus(pThreadPool);
	/*可用AddWorkLimit()替换看执行的效果*/
	pThreadPool->AddWorkUnlimit((void*)pThreadPool, thread_1, (void*)NULL);
	/*
	* 没加延迟发现连续投递任务时pthread_cond_wait()会收不到信号pthread_cond_signal() !!
	* 因为AddWorkUnlimit()进去后调用pthread_mutex_lock()把互斥锁锁上,导致pthread_cond_wait()
	* 收不到信号!!也可在AddWorkUnlimit()里面加个延迟,一般情况可能也遇不到这个问题
	*/
	usleep(10);	
	pThreadPool->AddWorkUnlimit((void*)pThreadPool, thread_2, (void*)nNumInput);
	usleep(10);
	pThreadPool->AddWorkUnlimit((void*)pThreadPool, thread_3, (void*)LogInput);
	usleep(10);
	DisplayPoolStatus(pThreadPool);
	nKillThread = 1;
	usleep(100);	/**< 先让线程退出 */
	DisplayPoolStatus(pThreadPool);
	nKillThread = 2;
	usleep(100);
	DisplayPoolStatus(pThreadPool);
	nKillThread = 3;
	usleep(100);
	DisplayPoolStatus(pThreadPool);
	pThreadPool->Destruct((void*)pThreadPool);
	return 0;
}
static void* thread_1(void* arg)
{
	printf("Thread 1 is running !\n");
	while(nKillThread != 1)
		usleep(10);
	return NULL;
}
static void* thread_2(void* arg)
{
	int nNum = (int)arg;
	
	printf("Thread 2 is running !\n");
	printf("Get Number %d\n", nNum);
	while(nKillThread != 2)
		usleep(10);
	return NULL;
}
static void* thread_3(void* arg)
{
	char *pLog = (char*)arg;
	
	printf("Thread 3 is running !\n");
	printf("Get String %s\n", pLog);
	while(nKillThread != 3)
		usleep(10);
	return NULL;
}
static void DisplayPoolStatus(CThread_pool_t* pPool)
{
	static int nCount = 1;
	
	printf("******************\n");
	printf("nCount = %d\n", nCount++);
	printf("max_thread_num = %d\n", pPool->GetMaxThreadNum((void*)pPool));
	printf("current_pthread_num = %d\n", pPool->GetCurThreadNum((void*)pPool));
	printf("current_pthread_task_num = %d\n", pPool->GetCurTaskThreadNum((void*)pPool));
	printf("cur_queue_size = %d\n", pPool->GetCurTaskNum((void*)pPool));
	printf("******************\n");
}

Lib_thread_pool.c:

/************************************************************************
* module			: 线程池实现
* file name		: lib_thread_pool.c
* Author 			: 
* version			: V1.0
* DATE			: 
* directory 		: 
* description		: 
* related document: 
* 
************************************************************************/
/*-----------------------includes-------------------------------*/
#include <stdio.h> 
#include <stdlib.h> 
#include <unistd.h> 
#include <sys/types.h> 
#include <pthread.h> 
#include <assert.h> 
#include <string.h>
#include "lib_thread_pool.h"
/*---------------constants/macro definition---------------------*/
/*---------------global variables definition-----------------------*/
/*---------------functions declaration--------------------------*/
static void * ThreadPoolRoutine (void *arg); 
/*---------------functions definition---------------------------*/
/****************************************************************
* function name 		: ThreadPoolAddWorkLimit
* functional description	: 向线程池投递任务,无空闲线程则阻塞
* input parameter		: pthis	线程池指针
					  process	回调函数
					  arg		回调函数的参数
* output parameter	: 
* return value			: 0 - 成功;-1 - 失败 
* history				: 
*****************************************************************/
static int ThreadPoolAddWorkLimit(void* pthis,void *(*process) (void *arg), void *arg) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
    worker_t *newworker = (worker_t *) malloc (sizeof (worker_t)); 
	if (NULL == newworker)
	{
		return -1;
	}
    newworker->process 	= process;	/**< 回调函数,在线程ThreadPoolRoutine()中执行 */
    newworker->arg 		= arg;		/**< 回调函数参数 */
    newworker->next 	= NULL;
    pthread_mutex_lock(&(pool->queue_lock)); 
	
    worker_t *member = pool->queue_head;	/**< 等待队列任务链表 */
    if (member != NULL) 
    { 
        while (member->next != NULL) 
        {
        	member = member->next; 
        }
        member->next = newworker;	/**< 放入链表尾 */
    } 
    else 
    { 
        pool->queue_head = newworker;	/**< 放入链表头 */
    } 
	
    assert (pool->queue_head != NULL); 
    pool->cur_queue_size++;		/**< 等待队列加1 */
	int FreeThreadNum = pool->current_pthread_num - pool->current_pthread_task_num;		
    if((0 == FreeThreadNum) && (pool->current_pthread_num < pool->max_thread_num))
    {/**< 如果没有空闲线程且池中当前线程数不超过可容纳最大线程 */
    	int current_pthread_num = pool->current_pthread_num;
    	pool->threadid = (pthread_t *) realloc(pool->threadid,(current_pthread_num + 1) * sizeof (pthread_t));	 /**< 新增线程 */
		pthread_create (&(pool->threadid[current_pthread_num]), NULL, ThreadPoolRoutine,  (void*)pool);
		pool->current_pthread_num++;	/**< 当前池中线程总数加1 */	
		
		pool->current_pthread_task_num++;	/**< 分配任务的线程数加1 */	
		pthread_mutex_unlock (&(pool->queue_lock)); 
    	pthread_cond_signal (&(pool->queue_ready));	/**< 发送信号给1个处于条件阻塞等待状态的线程 */	
		return 0;
    }
	pool->current_pthread_task_num++; 
    pthread_mutex_unlock(&(pool->queue_lock)); 
    pthread_cond_signal(&(pool->queue_ready));
//	usleep(10);	//看情况加
    return 0; 
} 
/****************************************************************
* function name 		: ThreadPoolAddWorkUnlimit
* functional description	: 向线程池投递任务
* input parameter		: pthis	线程池指针
					  process	回调函数
					  arg		回调函数的参数
* output parameter	: 
* return value			: 0 - 成功;-1 - 失败 
* history				: 
*****************************************************************/
static int ThreadPoolAddWorkUnlimit(void* pthis,void *(*process) (void *arg), void *arg) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
    worker_t *newworker = (worker_t *) malloc (sizeof (worker_t)); 
	
	if (NULL == newworker)
	{
		return -1;
	}
    newworker->process 	= process;	
    newworker->arg 		= arg; 		
    newworker->next 	= NULL;		
    pthread_mutex_lock(&(pool->queue_lock)); 
	
    worker_t *member = pool->queue_head; 
    if (member != NULL) 	
    { 
        while (member->next != NULL) 
        {
        	member = member->next; 
        }
        member->next = newworker; 
    } 
    else 
    { 
        pool->queue_head = newworker; 
    } 
	
    assert (pool->queue_head != NULL); 
    pool->cur_queue_size++; 
	int FreeThreadNum = pool->current_pthread_num - pool->current_pthread_task_num;
    if(0 == FreeThreadNum)	/**< 只判断是否没有空闲线程 */
    {
    	int current_pthread_num = pool->current_pthread_num;
    	pool->threadid = (pthread_t *) realloc(pool->threadid,(current_pthread_num + 1) * sizeof (pthread_t)); 
		pthread_create (&(pool->threadid[current_pthread_num]), NULL, ThreadPoolRoutine,  (void*)pool);
		pool->current_pthread_num++;
		if (pool->current_pthread_num > pool->max_thread_num)
		{
			pool->max_thread_num = pool->current_pthread_num;
		}
		
		pool->current_pthread_task_num++;
		pthread_mutex_unlock (&(pool->queue_lock)); 
    	pthread_cond_signal (&(pool->queue_ready)); 
		return 0;
    }
	
	pool->current_pthread_task_num++;
    pthread_mutex_unlock(&(pool->queue_lock)); 
    pthread_cond_signal(&(pool->queue_ready)); 	
//	usleep(10);	//看情况加
    return 0; 
} 
/****************************************************************
* function name 		: ThreadPoolGetThreadMaxNum
* functional description	: 获取线程池可容纳的最大线程数
* input parameter		: pthis	线程池指针
* output parameter	: 
* return value			: 线程池可容纳的最大线程数
* history				: 
*****************************************************************/
static int ThreadPoolGetThreadMaxNum(void* pthis) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
	
    pthread_mutex_lock(&(pool->queue_lock)); 
	int num = pool->max_thread_num;
    pthread_mutex_unlock(&(pool->queue_lock)); 
	
    return num; 
} 
/****************************************************************
* function name 		: ThreadPoolGetCurrentThreadNum
* functional description	: 获取线程池存放的线程数
* input parameter		: pthis	线程池指针
* output parameter	: 
* return value			: 线程池存放的线程数
* history				: 
*****************************************************************/
static int ThreadPoolGetCurrentThreadNum(void* pthis) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
	
    pthread_mutex_lock(&(pool->queue_lock)); 
	int num = pool->current_pthread_num;
    pthread_mutex_unlock(&(pool->queue_lock)); 
	
    return num; 
} 
/****************************************************************
* function name 		: ThreadPoolGetCurrentTaskThreadNum
* functional description	: 获取当前正在执行任务和已分配任务的线程数目和
* input parameter		: pthis	线程池指针
* output parameter	: 
* return value			: 当前正在执行任务和已分配任务的线程数目和
* history				: 
*****************************************************************/
static int ThreadPoolGetCurrentTaskThreadNum(void* pthis) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
	
    pthread_mutex_lock(&(pool->queue_lock)); 
	int num = pool->current_pthread_task_num;
    pthread_mutex_unlock(&(pool->queue_lock)); 
	
    return num; 
} 
/****************************************************************
* function name 		: ThreadPoolGetCurrentTaskNum
* functional description	: 获取线程池等待队列任务数
* input parameter		: pthis	线程池指针
* output parameter	: 
* return value			: 等待队列任务数
* history				: 
*****************************************************************/
static int ThreadPoolGetCurrentTaskNum(void* pthis) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
	
    pthread_mutex_lock(&(pool->queue_lock)); 
	int num = pool->cur_queue_size;
    pthread_mutex_unlock(&(pool->queue_lock)); 
	
    return num; 
} 
/****************************************************************
* function name 		: ThreadPoolDestroy
* functional description	: 销毁线程池
* input parameter		: pthis	线程池指针
* output parameter	: 
* return value			: 0 - 成功;-1 - 失败
* history				: 
*****************************************************************/
static int ThreadPoolDestroy (void *pthis) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)pthis;
	
    if (pool->shutdown) /**< 已销毁 */
    {
    	return -1;
    }
    pool->shutdown = 1;	/**< 销毁标志置位 */
	
    pthread_cond_broadcast (&(pool->queue_ready)); /**< 唤醒所有pthread_cond_wait()等待线程 */
    int i; 
    for (i = 0; i < pool->current_pthread_num; i++) 
    {
    	pthread_join (pool->threadid[i], NULL); /**< 等待所有线程执行结束 */
    }
	
    free (pool->threadid);	/**< 释放 */
    worker_t *head = NULL; 
	
    while (pool->queue_head != NULL) 
    { 
        head = pool->queue_head; 
        pool->queue_head = pool->queue_head->next; 
        free (head);	/**< 释放 */
    } 
	
    pthread_mutex_destroy(&(pool->queue_lock));	/**< 销毁 */
    pthread_cond_destroy(&(pool->queue_ready)); /**< 销毁 */     
    free (pool);	/**< 释放 */ 
    pool=NULL; 	
    return 0; 
} 
/****************************************************************
* function name 		: ThreadPoolRoutine
* functional description	: 线程池中运行的线程
* input parameter		: arg	线程池指针
* output parameter	: 
* return value			: NULL
* history				: 
*****************************************************************/
static void * ThreadPoolRoutine (void *arg) 
{ 
	CThread_pool_t *pool = (CThread_pool_t *)arg;
	
    while (1) 
    { 
        pthread_mutex_lock (&(pool->queue_lock)); /**< 上锁, pthread_cond_wait()调用会解锁*/
		
        while ((pool->cur_queue_size == 0) && (!pool->shutdown))	/**< 队列没有等待任务*/
        { 
            pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock)); 	/**< 条件锁阻塞等待条件信号*/
		} 
        if (pool->shutdown) 
        { 
            pthread_mutex_unlock (&(pool->queue_lock)); 
            pthread_exit (NULL); 	/**< 释放线程 */
        } 
        assert (pool->cur_queue_size != 0); 
        assert (pool->queue_head != NULL); 
         
        pool->cur_queue_size--; 	/**< 等待任务减1,准备执行任务*/ 
        worker_t *worker 	= pool->queue_head;	/**< 取等待队列任务结点头*/ 
        pool->queue_head 	= worker->next; 	/**< 链表后移 */ 
		
        pthread_mutex_unlock (&(pool->queue_lock)); 
        (*(worker->process)) (worker->arg); 	/**< 执行回调函数 */ 
        pthread_mutex_lock (&(pool->queue_lock)); 
		
		pool->current_pthread_task_num--;	/**< 函数执行结束 */ 
        free (worker); 	/**< 释放任务结点 */
        worker = NULL; 
		if ((pool->current_pthread_num - pool->current_pthread_task_num) > pool->free_pthread_num)
		{
			pthread_mutex_unlock (&(pool->queue_lock)); 
			break;	/**< 当池中空闲线程超过 free_pthread_num则将线程释放回操作系统 */
		}
        pthread_mutex_unlock (&(pool->queue_lock)); 		
    } 
	
	pool->current_pthread_num--;	/**< 当前池中线程数减1 */
    pthread_exit (NULL);	/**< 释放线程*/
    return (void*)NULL;
} 
/****************************************************************
* function name 		: ThreadPoolConstruct
* functional description	: 创建线程池
* input parameter		: max_num	线程池可容纳的最大线程数
					  free_num	线程池允许存在的最大空闲线程,超过则将线程释放回操作系统
* output parameter	: 
* return value			: 线程池指针
* history				: 
*****************************************************************/
CThread_pool_t* ThreadPoolConstruct(int max_num,int free_num) 
{ 
    CThread_pool_t *pool = (CThread_pool_t *) malloc (sizeof (CThread_pool_t)); 
	if (NULL == pool)
	{
		return NULL;
	}
	memset(pool, 0, sizeof(CThread_pool_t));
	
    pthread_mutex_init (&(pool->queue_lock), NULL);	/**< 初始化互斥锁 */
    pthread_cond_init (&(pool->queue_ready), NULL);	/**< 初始化条件变量 */ 
    pool->queue_head 				= NULL; 
    pool->max_thread_num 			= max_num;	/**< 线程池可容纳的最大线程数 */
    pool->cur_queue_size 			= 0; 
	pool->current_pthread_task_num 	= 0;
    pool->shutdown 					= 0; 
	pool->current_pthread_num 		= 0;
	pool->free_pthread_num 			= free_num;	/**< 线程池允许存在的最大空闲线程 */
	pool->threadid					= NULL;
    pool->threadid 					= (pthread_t *) malloc (max_num * sizeof (pthread_t)); 
	pool->AddWorkUnlimit			= ThreadPoolAddWorkUnlimit;	/**< 给函数指针赋值 */
	pool->AddWorkLimit				= ThreadPoolAddWorkLimit;
	pool->Destruct					= ThreadPoolDestroy;
	pool->GetMaxThreadNum			= ThreadPoolGetThreadMaxNum;
	pool->GetCurThreadNum			= ThreadPoolGetCurrentThreadNum;
	pool->GetCurTaskThreadNum		= ThreadPoolGetCurrentTaskThreadNum;
	pool->GetCurTaskNum				= ThreadPoolGetCurrentTaskNum;
	
    int i = 0; 
    for (i = 0; i < max_num; i++) 
    {  
		pool->current_pthread_num++;	/**< 当前池中的线程数 */
        pthread_create (&(pool->threadid[i]), NULL, ThreadPoolRoutine, (void*)pool);	/**< 创建线程 */
		usleep(1000);
    } 
	return pool;
} 
/****************************************************************
* function name 		: ThreadPoolConstructDefault
* functional description	: 创建线程池,以默认的方式初始化,未创建线程
* input parameter		: 
* output parameter	: 
* return value			: 线程池指针
* history				: 
*****************************************************************/
CThread_pool_t* ThreadPoolConstructDefault(void) 
{ 
    CThread_pool_t *pool = (CThread_pool_t *) malloc (sizeof (CThread_pool_t)); 
	if (NULL == pool)
	{
		return NULL;
	}
	memset(pool, 0, sizeof(CThread_pool_t));
	
    pthread_mutex_init(&(pool->queue_lock), NULL); 
    pthread_cond_init(&(pool->queue_ready), NULL); 
    pool->queue_head 				= NULL; 
    pool->max_thread_num 			= DEFAULT_MAX_THREAD_NUM;	/**< 默认值 */
    pool->cur_queue_size 			= 0; 
	pool->current_pthread_task_num 	= 0;
    pool->shutdown 					= 0; 
	pool->current_pthread_num 		= 0;
	pool->free_pthread_num 			= DEFAULT_FREE_THREAD_NUM;	/**< 默认值 */
	pool->threadid					= NULL;
	pool->AddWorkUnlimit			= ThreadPoolAddWorkUnlimit;
	pool->AddWorkLimit				= ThreadPoolAddWorkLimit;
	pool->Destruct					= ThreadPoolDestroy;
	pool->GetMaxThreadNum			= ThreadPoolGetThreadMaxNum;
	pool->GetCurThreadNum			= ThreadPoolGetCurrentThreadNum;
	pool->GetCurTaskThreadNum		= ThreadPoolGetCurrentTaskThreadNum;
	pool->GetCurTaskNum				= ThreadPoolGetCurrentTaskNum;
	
	return pool;
}
Lib_thread_pool.h:
/************************************************************************
* module			: 线程池头文件
* file name		: lib_thread_pool.h
* Author 			: 
* version			: V1.0
* DATE			: 
* directory 		: 
* description		: 
* related document: 
* 
************************************************************************/
/*-----------------------includes-------------------------------*/
#ifndef __PTHREAD_POOL_H__
#define __PTHREAD_POOL_H__
#include <pthread.h>
/*---------------constants/macro definition---------------------*/
#define DEFAULT_MAX_THREAD_NUM		100
#define DEFAULT_FREE_THREAD_NUM		10	
typedef struct worker_t worker_t;
typedef struct CThread_pool_t CThread_pool_t;
/*---------------global variables definition-----------------------*/
/*线程池任务结点*/
struct worker_t
{
	void *(*process) (void *arg);	/**< 回调函数 */
    int   paratype;					/**< 函数类型(预留) */
    void *arg;						/**< 回调函数参数 */
    struct worker_t *next;			/**< 连接下一个任务结点 */
};
/*线程池控制器*/
struct CThread_pool_t
{
	pthread_mutex_t queue_lock;	/**< 互斥锁 */
    pthread_cond_t queue_ready;	/**< 条件变量 */
    worker_t *queue_head;	/**< 任务结点链表,保存所有投递的任务 */
    int shutdown;			/**< 线程池销毁标志,1 - 销毁 */
    pthread_t *threadid;	/**< 线程ID */
    int max_thread_num;		/**< 线程池可容纳的最大线程数 */
	int current_pthread_num;	/**< 当前线程池存放的线程数 */
	int current_pthread_task_num;	/**< 当前正在执行任务和已分配任务的线程数目和 */
    int cur_queue_size;		/**< 当前等待队列的任务数目 */
	int	free_pthread_num;	/**< 线程池内允许存在的最大空闲线程数 */
	
	/****************************************************************
	* function name 		: ThreadPoolAddWorkLimit
	* functional description	: 向线程池投递任务
	* input parameter		: pthis	线程池指针
						  process	回调函数
						  arg		回调函数的参数
	* output parameter	: 
	* return value			: 0 - 成功;-1 - 失败 
	* history				: 
	*****************************************************************/
	int (*AddWorkUnlimit)(void* pthis,void *(*process) (void *arg), void *arg); 
	/****************************************************************
	* function name 		: ThreadPoolAddWorkUnlimit
	* functional description	: 向线程池投递任务,无空闲线程则阻塞
	* input parameter		: pthis	线程池指针
						  process	回调函数
						  arg		回调函数的参数
	* output parameter	: 
	* return value			: 0 - 成功;-1 - 失败 
	* history				: 
	*****************************************************************/
	int (*AddWorkLimit)(void* pthis,void *(*process) (void *arg), void *arg); 
	
	/****************************************************************
	* function name 		: ThreadPoolGetThreadMaxNum
	* functional description	: 获取线程池可容纳的最大线程数
	* input parameter		: pthis	线程池指针
	* output parameter	: 
	* return value			: 线程池可容纳的最大线程数
	* history				: 
	*****************************************************************/
	int (*GetMaxThreadNum) (void *pthis); 
	/****************************************************************
	* function name 		: ThreadPoolGetCurrentThreadNum
	* functional description	: 获取线程池存放的线程数
	* input parameter		: pthis	线程池指针
	* output parameter	: 
	* return value			: 线程池存放的线程数
	* history				: 
	*****************************************************************/	
	int (*GetCurThreadNum) (void *pthis); 
	
	/****************************************************************
	* function name 		: ThreadPoolGetCurrentTaskThreadNum
	* functional description	: 获取当前正在执行任务和已分配任务的线程数目和
	* input parameter		: pthis	线程池指针
	* output parameter	: 
	* return value			: 当前正在执行任务和已分配任务的线程数目和
	* history				: 
	*****************************************************************/
	int (*GetCurTaskThreadNum) (void *pthis); 
	
	/****************************************************************
	* function name 		: ThreadPoolGetCurrentTaskNum
	* functional description	: 获取线程池等待队列任务数
	* input parameter		: pthis	线程池指针
	* output parameter	: 
	* return value			: 等待队列任务数
	* history				: 
	*****************************************************************/
	int (*GetCurTaskNum) (void *pthis); 
	
	/****************************************************************
	* function name 		: ThreadPoolDestroy
	* functional description	: 销毁线程池
	* input parameter		: pthis	线程池指针
	* output parameter	: 
	* return value			: 0 - 成功;-1 - 失败
	* history				: 
	*****************************************************************/
	int (*Destruct) (void *pthis); 
};
/*---------------functions declaration--------------------------*/
/****************************************************************
* function name 		: ThreadPoolConstruct
* functional description	: 创建线程池
* input parameter		: max_num	线程池可容纳的最大线程数
					  free_num	线程池允许存在的最大空闲线程,超过则将线程释放回操作系统
* output parameter	: 
* return value			: 线程池指针
* history				: 
*****************************************************************/
CThread_pool_t* ThreadPoolConstruct(int max_num,int free_num);
/****************************************************************
* function name 		: ThreadPoolConstructDefault
* functional description	: 创建线程池,以默认的方式初始化,未创建线程
* input parameter		: 
* output parameter	: 
* return value			: 线程池指针
* history				: 
*****************************************************************/
CThread_pool_t* ThreadPoolConstructDefault(void);
#endif

Makefile:

edit:main.o lib_thread_pool.o
	gcc -pthread -o edit main.o lib_thread_pool.o
main.o:main.c lib_thread_pool.h
	gcc -pthread -c main.c
lib_thread_pool.o:lib_thread_pool.c lib_thread_pool.h
	gcc -pthread -c lib_thread_pool.c
.PHONY : clean
clean:
	rm -rf *.o

运行:

Make
./edit
Make clean

程序运行截图:
在这里插入图片描述
3.改造属于自己的线程池代码
Threadpool.h:

#ifndef __THREAD_POOL_H__
#define __THREAD_POOL_H__
#include <pthread.h>
/**********************************************************************
 任务回调函数,也可根据需要自行修改
*********************************************************************/
typedef void *(*pool_task_f)(void *arg);
/**********************************************************************
 任务句柄
*********************************************************************/
typedef struct _task{
	pool_task_f process;
/*回调函数,任务运行时会调用此函数,注意也可声明成其它形式*/
	void *arg;
          /*回调函数的参数*/
	struct _task *next;}pool_task;
/**********************************************************************
 线程池句柄
*********************************************************************/
typedef struct{
	pthread_t *threadid;
		/* 线程号 */
	int threads_limit;
			/* 线程池中允许的活动线程数目 */
	int destroy_flag;
			/* 是否销毁线程池 , 0销毁,1不销毁*/
	pool_task *queue_head;
	    /* 链表结构,线程池中所有等待任务 */
	int task_in_queue;
			/* 当前等待队列的任务数目 */
	pthread_mutex_t queue_lock;
	/* 锁 */
	pthread_cond_t queue_ready;
	/* 条件变量 */
}pool_t;
/*********************************************************************
*功能:    初始化线程池结构体并创建线程
*参数:    pool:线程池句柄
*        threads_limit:线程池中线程的数量
*返回值:	无
*********************************************************************/
void pool_init(pool_t *pool, int threads_limit);
/*********************************************************************
*功能:    销毁线程池,等待队列中的任务不会再被执行,
*        但是正在运行的线程会一直,把任务运行完后再退出
*参数:    线程池句柄
*返回值:	成功:0,失败非0
*********************************************************************/
int pool_uninit(pool_t *pool);
/*********************************************************************
*功能:    向线程池中添加一个任务
*参数:    pool:线程池句柄
*        process:任务处理函数
*        arg:任务参数
*返回值:	0
*********************************************************************/
int pool_add_task(pool_t *pool, pool_task_f process, void *arg);
#endif

Threadpool.c:

#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <assert.h>
#include "threadpool.h"
static void *pool_thread_server(void *arg);
/*********************************************************************
*功能:    初始化线程池结构体并创建线程
*参数:    pool:线程池句柄
*        threads_limit:线程池中线程的数量
*返回值:	无
*********************************************************************/
void pool_init(pool_t *pool, int threads_limit){
	pool->threads_limit = threads_limit;
	pool->queue_head = NULL;	pool->task_in_queue = 0;
	pool->destroy_flag = 0;
	/*创建存放线程ID的空间*/
	pool->threadid = (pthread_t *)calloc(threads_limit, sizeof(pthread_t));
	int i = 0;
	/*初始化互斥锁和条件变量*/
	pthread_mutex_init(&(pool->queue_lock), NULL);
	pthread_cond_init(&(pool->queue_ready), NULL);	
/*循环创建threads_limit个线程*/
	for (i = 0; i < threads_limit; i++){
		pthread_create(&(pool->threadid[i]), NULL, pool_thread_server, pool);
	}
	return;
}
/*********************************************************************
*功能:    销毁线程池,等待队列中的任务不会再被执行,
*        但是正在运行的线程会一直,把任务运行完后再退出
*参数:    线程池句柄*返回值:  成功:0,失败非0
*********************************************************************/
int pool_uninit(pool_t *pool){
	pool_task *head = NULL;
	int i;
		pthread_mutex_lock(&(pool->queue_lock));
	if(pool->destroy_flag)/* 防止两次调用 */
		return -1;
	pool->destroy_flag = 1;
	pthread_mutex_unlock(&(pool->queue_lock));
	/* 唤醒所有等待线程,线程池要销毁了 */
	pthread_cond_broadcast(&(pool->queue_ready));
	/* 阻塞等待线程退出,否则就成僵尸了 */
	for (i = 0; i < pool->threads_limit; i++)
		pthread_join(pool->threadid[i], NULL);
	free(pool->threadid);
	/* 销毁等待队列 */
	pthread_mutex_lock(&(pool->queue_lock));
	while(pool->queue_head != NULL){
		head = pool->queue_head;
		pool->queue_head = pool->queue_head->next;
		free(head);
	}
	pthread_mutex_unlock(&(pool->queue_lock));
	/*条件变量和互斥量也别忘了销毁*/
	pthread_mutex_destroy(&(pool->queue_lock));
	pthread_cond_destroy(&(pool->queue_ready));
	return 0;
}
/*********************************************************************
*功能:    向任务队列中添加一个任务
*参数:    pool:线程池句柄
*        process:任务处理函数
*        arg:任务参数*返回值:	无*********************************************************************/
static void enqueue_task(pool_t *pool, pool_task_f process, void *arg){
	pool_task *task = NULL;
	pool_task *member = NULL;	
		pthread_mutex_lock(&(pool->queue_lock));
		if(pool->task_in_queue >= pool->threads_limit){
		printf("task_in_queue > threads_limit!\n");
		pthread_mutex_unlock (&(pool->queue_lock));
		return;
	
}		task = (pool_task *)calloc(1, sizeof(pool_task));
	assert(task != NULL);
	task->process = process;
	task->arg = arg;
	task->next = NULL;
	pool->task_in_queue++;
	member = pool->queue_head;
	if(member != NULL){
		while(member->next != NULL)
	/* 将任务加入到任务链连的最后位置. */
			member = member->next;
		member->next = task;
	}else{
		pool->queue_head = task;
	/* 如果是第一个任务的话,就指向头 */	}
	printf("\ttasks %d\n", pool->task_in_queue);
	/* 等待队列中有任务了,唤醒一个等待线程 */
	pthread_cond_signal (&(pool->queue_ready));
	pthread_mutex_unlock (&(pool->queue_lock));}
/*********************************************************************
*功能:    从任务队列中取出一个任务
*参数:    线程池句柄
*返回值:	任务句柄
*********************************************************************/
static pool_task *dequeue_task(pool_t *pool){
	pool_task *task = NULL;
		pthread_mutex_lock(&(pool->queue_lock));
	/* 判断线程池是否要销毁了 */
	if(pool->destroy_flag){
		pthread_mutex_unlock(&(pool->queue_lock));
		printf("thread 0x%lx will be destroyed\n", pthread_self());
		pthread_exit(NULL);
	}
	/* 如果等待队列为0并且不销毁线程池,则处于阻塞状态 */
	if(pool->task_in_queue == 0){
		while((pool->task_in_queue == 0) && (!pool->destroy_flag)){
			printf("thread 0x%lx is leisure\n", pthread_self());
			/* 注意:pthread_cond_wait是一个原子操作,等待前会解锁,唤醒后会加锁 */			pthread_cond_wait(&(pool->queue_ready), &(pool->queue_lock));
		}
	}else{
		/* 等待队列长度减去1,并取出队列中的第一个元素 */
		pool->task_in_queue--;
		task = pool->queue_head;
		pool->queue_head = task->next;
		printf("thread 0x%lx received a task\n", pthread_self());
	}
	pthread_mutex_unlock(&(pool->queue_lock));
	return task;}
/*********************************************************************
*功能:    向线程池中添加一个任务
*参数:    pool:线程池句柄
*        process:任务处理函数
*        arg:任务参数*返回值:	0
*********************************************************************/
int pool_add_task(pool_t *pool, pool_task_f process, void *arg){
	enqueue_task(pool, process, arg);
	return 0;}
/*********************************************************************
*功能:    线程池服务程序
*参数:    略
*返回值:  略
*********************************************************************/
static void *pool_thread_server(void *arg){
	pool_t *pool = NULL;
		pool = (pool_t *)arg;
	while(1){
		pool_task *task = NULL;
		task = dequeue_task(pool);
		/*调用回调函数,执行任务*/
		if(task != NULL){
			printf ("thread 0x%lx is busy\n", pthread_self());
			task->process(task->arg);
			free(task);
			task = NULL;
		}
	}
	/*这一句应该是不可达的*/
	pthread_exit(NULL);
	 	return NULL;
} 

Main.c:

#include <stdio.h>
#include <unistd.h>
#include "threadpool.h"
/*********************************************************************
*功能:      任务处理函数
*参数:	  无
*返回值:    NULL
*********************************************************************/
void *task_test(void *arg){
	printf("\t\tworking on task %d\n", (int)arg);
	sleep(1);
	  /*休息一秒,延长任务的执行时间*/
	return NULL;
}
int main (int argc, char *argv[]){
  	pool_t pool;
	int i = 0;
	pool_init(&pool, 2);//初始化线程池
	sleep(1);
	for(i = 0; i < 5; i++){
		sleep(1);
		pool_add_task(&pool, task_test, (void *)i);//向线程池中添加一个任务
	}
	sleep(4);
	pool_uninit(&pool);//销毁线程池
	return 0;
} 

运行:

gcc -L/usr/DirectFB25/lib -I/usr/DirectFB25/include/directfb -lpthread -ldl main.c threadpool.c threadpool.h -o edit
./edit

运行截图如下:
在这里插入图片描述

  • 5
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Knight_V_Schumacher

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值