【Linux】线程池
首先,线程池是什么?顾名思义,就是把一堆开辟好的线程放在一个池子里统一管理,就是一个线程池。
其次,为什么要用线程池,难道来一个请求给它申请一个线程,请求处理完了释放线程不行么?也行,但是如果创建线程和销毁线程的时间比线程处理请求的时间长,而且请求很多的情况下,我们的CPU资源都浪费在了创建和销毁线程上了,所以这种方法的效率比较低,于是,我们可以将若干已经创建完成的线程放在一起统一管理,如果来了一个请求,我们从线程池中取出一个线程来处理,处理完了放回池内等待下一个任务,线程池的好处是避免了繁琐的创建和结束线程的时间,有效的利用了CPU资源。
功能:节省大量线程创建销毁成本,避免线程创建过多导致程序出错。
分类:
1.启动时就创建固定数量的线程,一直处理请求------请求比较多,耗时较短。
2.启动时不创建线程,当有请求时找空闲线程,如果没有空闲线程,就创建一个工作线程,如果工作线程等待超时,则工作线程退出释放资源。-------请求一般较少,耗时较长,防止峰值压力。
线程池 = 多个线程+任务队列
用第一种方式实现一个简单的线程池:
#include<iostream>
#include<time.h>
#include<queue>
#include<stdlib.h>
#include<unistd.h>
#include<pthread.h>
using namespace std;
class Task
{
public:
void SetData(void* data)
{
_data = data;
}
bool Run()
{
srand(time(NULL));
int nsec = rand()%5;
cout <<"ID: " << pthread_self() << " run data:-------"
<<(char*)_data << "-------sleep " << nsec << endl;
sleep(nsec);
return true;
}
private:
void* _data;
};
class ThreadPool
{
public:
ThreadPool(int max_thread = 5, int max_queue = 10)
:_max_thread(max_thread)
,_cur_thread(max_thread)
,_stop_flag(0)
,_cap(max_queue)
{
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_empty,www.leyou2.net NULL);
pthread_cond_init(&_full, NULL);
}
~ThreadPool()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_empty);
pthread_cond_destroy(&_full);
}
bool Init()
{
pthread_t tid;
for(int i = 0; i < _max_thread; ++i)
{
int ret = pthread_create(&tid, NULL, thr_start, (void*)this);
if(ret != 0)
{
cout << "pthread_create error" << endl;
return false;
}
pthread_detach(tid);
}
}
bool AddTask(Task* t)
{
pthread_mutex_lock(&_mutex);
while(Full())
{
pthread_cond_wait(&_full, &_mutex);
}
QueuePush(t);
pthread_cond_signal(&_empty);
pthread_mutex_unlock(&_mutex);
return true;
}
bool Stop()
{
pthread_mutex_lock(www.thd178.com/ &_mutex);
if(_stop_flag == 1)
{
pthread_mutex_unlock(&_mutex);
return false;
}
_stop_flag = 1;
while(_cur_thread > 0)
{
pthread_cond_broadcast(&_empty);
pthread_cond_wait(&_full, &_mutex);
}
pthread_mutex_unlock(&_mutex);
return false;
}
private:
bool Empty()
{
return _list.empty();
}
bool Full()
{
return (_cap == _list.size());
}
bool QueuePush(Task*www.michenggw.com task)
{
_list.push(task);
return true;
}
bool QueuePop(Task** task)
{
*task = _list.front();
_list.pop();
return true;
}
static void* thr_start(void *arg)
{
ThreadPool* p = (ThreadPool*)arg;
while(1)
{
pthread_mutex_lock(&p->_mutex);
//如果队列为空,且不是退出状态,陷入等待
while(p->Empty() && p->_stop_flag != 1)
pthread_cond_wait(&p->_empty, &p->_mutex);
//如果队列为空,且处于退出状态,则退出
//退出前当前线程数-1,解锁
if(p->Empty() && p->_stop_flag == 1)
{
cout << "--------thread exit" << endl;
p->_cur_thread--;
pthread_mutex_unlock(&p->_mutex);
pthread_cond_signal(www.ysyl157.com&p->_full);
pthread_exit(NULL);
}
Task *task;
p->QueuePop(&task);
pthread_mutex_unlock(&p->_mutex);
pthread_cond_signal(&p->_full);
//任务的执行,需要放在解锁外面,因为我们不知道任务需要执行多长时间
//如果先运行后解锁,有可能其他线程一直无法获取任务
task->Run();
}
return NULL;
}
private:
int _max_thread;//最大线程数量
int _cur_thread;//当前线程数量
int _stop_flag;//线程池中线程的退出标志
size_t _cap; //队列最大节点数
queue<Task*> _list;//线程池 任务队列
pthread_mutex_t _mutex;
pthread_cond_t _empty;
pthread_cond_t _full;
};
int main()
{
ThreadPool pool;
pool.Init();
Task task[10];
char* c = "hello world!!!";
for(int i = 0; i < 10; ++i)
{
sleep(1);
task[i].SetData((void*)c);
cout << "add task: " << c <<endl;
pool.AddTask(&task[i]);
}
pool.Stop();
return 0;
【Linux】线程池的更多相关文章
- linux线程池thrmgr源码解析
linux线程池thrmgr源码解析 1 thrmgr线程池的作用 thrmgr线程池的作用是提高程序的并发处理能力,在多CPU的服务器上运行程序,可以并发执行多个任务. 2 ...
- 一个简单的linux线程池(转-wangchenxicool)
线程池:简单地说,线程池 就是预先创建好一批线程,方便.快速地处理收到的业务.比起传统的到来一个任务,即时创建一个线程来处理,节省了线程的创建和回收的开销,响应更快,效率更高. 在linux中,使用的 ...
- 非常精简的Linux线程池实现(一)——使用互斥锁和条件变量
线程池的含义跟它的名字一样,就是一个由许多线程组成的池子. 有了线程池,在程序中使用多线程变得简单.我们不用再自己去操心线程的创建.撤销.管理问题,有什么要消耗大量CPU时间的任务通通直接扔到线程池里 ...
- Linux线程池的实现
线程池的实现 1:自定义封装的条件变量 //condition.h #ifndef _CONDITION_H_ #define _CONDITION_H_ #include <pthread.h ...
- linux线程池
typedef struct task_node { void *arg; /* fun arg. */ void *(*fun) (void *); /* the real work of the ...
- Linux线程池在server上简单应用
一.问题描写叙述 如今以C/S架构为例.client向server端发送要查找的数字,server端启动线程中的线程进行对应的查询.将查询结果显示出来. 二.实现方案 1. 整个project以cli ...
- Linux下简易线程池
线程池简介 线程池是可以用来在后台执行多个任务的线程集合. 这使主线程可以自由地异步执行其他任务.线程池通常用于服务器应用程序. 每个传入请求都将分配给线程池中的一个线程,因此可以异步处理请求,而不会 ...
- 线程池(Linux实现)
讨论QQ群:135202158 本文技术参考了sourceforge项目c thread pool,链接:http://sourceforge.net/projects/cthpool/ 线程池如上一 ...
- Linux平台下线程池的原理及实现
转自:http://blog.csdn.net/lmh12506/article/details/7753952 前段时间在github上开了个库,准备实现自己的线程池的,因为换工作的事,一直也没有实 ...
- 高效线程池之无锁化实现(Linux C)
from:http://blog.csdn.net/xhjcehust/article/details/45844901 笔者之前练手写过一个小的线程池版本(已上传至https://github.co ...
随机推荐
- python-time模块、sys模块、os模块以及大量实例
模块 通俗的说模块就把一个已经写好的带有可使用的函数的文件,通过文件名进行导入,然后调用里面的函数等来完成所需功能,模块封装了你需要实现功能的代码,使用者只需调用即可,简化代码量,缩短编程时间. ti ...
- 实现一个带有指纹加密功能的笔记本(Android)第一部分
自己经常会忘记一些密码什么的,想把这些密码保存下来,但是别人做的软件总有一点不安全的感觉,所以自己动手做了一个带有指纹加密的笔记本. 以下是本工程用到的一些第三方包 compile 'org.gree ...
- webapi到处excel
最近项目用的webapi前几天做了个导出excel功能,给大家分享下,自己也记录下... 在用的过程中,可以直接请求就可以得到下载的excel文件,在实际的项目中可以通过js打开新页面,encodeU ...
- python基础——列表、字典
Python核心数据类型--列表 列表是一个任意类型的对象的位置相关的有序集合,它没有固定的大小.大小可变的,通过偏移量进行赋值以及其他各种列表的方法进行调用,能够修改列表.其他更多的功能可以查阅py ...
- 初识Continuation
本文来自网易云社区 作者:陆艺 上学时看了SICP之后就对scheme这个看上去比较古怪的语言产生了兴趣. 虽然书里并没有涉及scheme太多语法以及语言上特性的一些东西, 作为一个喜欢折腾的人, 手 ...
- 三种block
block的实现原理是C语言的函数指针. 函数指针即函数在内存中的地址,通过这个地址可以达到调用函数的目的. Block是NSObject的子类,拥有NSObject的所有属性,所以block对象也有 ...
- IDA动态调试SO文件
1. 所需工具 IDA Pro 6.6. 安卓SDK工具 2. 模拟器设置 将ida所在目录的dbgsrv文件夹内的android_server文件push到模拟器中. 设置777属性 启动调试服务器 ...
- C#3DES加密了解一下
最近一个项目中,因为服务端是用的java开发的,客户端是用的C#,由于通信部分采用到了3DES加密,所以做个记录,以备以后需要的时候直接用. 这是对方(java)的加密算法,和网上流传的代码也差不多( ...
- python学习总结----简单数据结构
mini-web服务器 - 能够完成简单的请求处理 - 使用http协议 - 目的:加深对网络编程的认识.为后面阶段学习web做铺垫 简单数据结构 - 排列组合 import itertools # ...
- python 基础篇 13 迭代器与生成器
13. 前⽅⾼能-迭代器和⽣成器本节主要内容:1. 迭代器2. ⽣成器 ⼀. 迭代器我们之前⼀直在⽤可迭代对象进⾏迭代操作. 那么到底什么是可迭代对象. 本⼩节主要讨论可迭代对象. ⾸先我们先回顾⼀下 ...