首页 / LINUX / Linux线程(六)
Linux线程(六)
内容导读
互联网集市收集整理的这篇技术教程文章主要介绍了Linux线程(六),小编现在分享给大家,供广大互联网技能从业者学习和参考。文章包含5018字,纯文字阅读大概需要8分钟。
内容图文
![Linux线程(六)](/upload/InfoBanner/zyjiaocheng/943/8f6afb8b126b4a30af63731ebb22e618.jpg)
Linux线程(六)
一、线程池:
1.线程池:
- 线程池是一种使用模式。线程过多会带来调度开销,进而影响缓存的局部性和整体性能。而线程池维护着多个线程,等待监督管理者分配可并发执行的任务。这避免了在处理短时间任务时创建和销毁线程的代价。线程池内部不仅能够保证内核的充分利用,还能防止过度调度。可线程的数量应该取决于可用的并发处理器、处理器内核、内存、网络socket等的数量
2.应用场景:
- 需要大量的线程来完成任务,且完成任务的时间比较短。Web服务器完成网页请求这样的任,非常适合使用线程池来完成。因为单个任务小,而任务量巨大。想象一下热门网站的点击次数和速度。但相对于长时间的任务。比如一个Telnet链接。线程池的优点就不明显了,因为Telnet会话时间比线程创建时间大多了
- 对性能要求比较苛刻的应用。比如服务器同一时刻要快速响应大量客户的请求
- 接受突发性的大量请求,但不至于使服务器因此产生大量的线程应用。突发性大量客户请求,在没有线程池的情况下,将产生大量线程,虽然理论上大部分操作系统线程数量数目最大值不是问题,但是短时间内产生大量线程可能使内存达到极限出现错误
3.线程池种类:
- 任务队列控制的线程池模型,
- 工作线程控制的线程池模型,
- 主控线程控制的线程池模型
4.线程池事例:
- 创建固定数量的线程池,循环从任务队列中获取任务对象
- 获取到任务对象后,执行任务对象的任务接口
threadpool.hpp
#ifndef __M_POOL_H__
#define __M_POOL_H__
#include <iostream>
#include <queue>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <pthread.h>
#define MAX_THREAD 3
#define MAX_QUEUE 10
class MyTask
{
private:
int data;
public:
MyTask() {}
~MyTask() {}
void SetData(int _data)
{
data = _data;
}
v
oid Run()
{
int t = rand() % 5;
printf("thread:%lu sleep %d sec, execute data:%d\n", pthread_self(), t, data);
sleep(t);
}
};
class MyThreadPool
{
private:
int max_thread; //线程池中最大线程数
int cur_thread; //当前线程池中的线程数
int keep_running;//用于停止线程池中线程的标志
int max_queue; //队列的最大节点数
pthread_t *tid; //线程的线程ID
std::queue<MyTask *> task_list;
pthread_mutex_t mutex;
pthread_cond_t empty;
pthread_cond_t full;
void ThreadLock()
{
pthread_mutex_lock(&mutex);
}
void ThreadUnLock()
{
pthread_mutex_unlock(&mutex);
}
void ConsumerWait()
{
pthread_cond_wait(&empty, &mutex);
}
void ConsumerNotify()
{
pthread_cond_signal(&empty);
}
void ProducterWait()
{
pthread_cond_wait(&full, &mutex);
}
void ProducterNotify()
{
pthread_cond_signal(&full);
}
bool ThreadIsRunning()
{
return (keep_running == 0 ? false : true);
}
void ThreadExit()
{
cur_thread--;
//线程池中的线程退出时通知一下主线程
printf("thread:%lu exit\n", pthread_self());
ProducterNotify();
pthread_exit(NULL);
}
bool QueueIsEmpty()
{
return (task_list.size() == 0 ? true : false);
}
bool QueueIsFull()
{
return (task_list.size() == max_queue ? true : false);
}
void PopTask(MyTask **task)
{
*task = task_list.front();
task_list.pop();
return;
}
void PushTask(MyTask *task)
{
task_list.push(task);
}
static void *thread_routine(void *arg)
{
MyThreadPool *pthreadpool = (MyThreadPool*)arg;
while(1) {
pthreadpool->ThreadLock();
//若当前是运行状态,并且没有任务则挂起等待
while(pthreadpool->QueueIsEmpty() && pthreadpool->ThreadIsRunning()) {
pthreadpool->ConsumerWait();
} /
/若当前是非运行状态,且没有任务则退出线程
//若当前时非运行状态,但是队列中有任务则需要将任务执行完毕后才能退出
if (!pthreadpool->ThreadIsRunning() && pthreadpool->QueueIsEmpty()) {
pthreadpool->ThreadUnLock();
pthreadpool->ThreadExit();
} /
/能够走下来,则任务队列不为空,那么获取一个任务执行
MyTask *task;
pthreadpool->PopTask(&task);
pthreadpool->ProducterNotify();
pthreadpool->ThreadUnLock();
//执行任务,不能在锁内,否则导致其它线程饥饿
task->Run();
}
return NULL;
public:
MyThreadPool(int _max_thread = MAX_THREAD, int _max_queue= MAX_QUEUE):\
max_thread(_max_thread), max_queue(_max_queue), cur_thread(_max_thread),
keep_running(1)
{
int i = 0;
printf("create thread:%d-%d\n", max_thread, max_queue);
tid = (pthread_t*)malloc(sizeof(pthread_t) * _max_thread);
pthread_mutex_init(&mutex, NULL);
pthread_cond_init(&full, NULL);
pthread_cond_init(&empty, NULL);
//创建固定数量的线程,等待执行任务
for(i = 0; i < _max_thread; i++) {
int ret = pthread_create(&tid[i], NULL, thread_routine, (void*)this);
if (ret != 0) {
printf("create thread error\n");
exit(0);
}
pthread_detach(tid[i]);
}
} ~
MyThreadPool()
{
pthread_mutex_destroy(&mutex);
pthread_cond_destroy(&full);
pthread_cond_destroy(&empty);
}
/
/向线程池任务队列中添加任务
bool AddTaskToPool(MyTask *task)
{
ThreadLock();
while(QueueIsFull()) {
ProducterWait();
}
PushTask(task);
printf("add task to pool\n");
ConsumerNotify();
ThreadUnLock();
return true;
}
void StopThreadPool()
{
//若已经调用过线程池退出,则返回
if (keep_running == 0) {
return;
}
ThreadLock();
keep_running = 0;
//如果还有线程没有退出,则挂起等待
//等待所有线程将队列中的所有任务都执行完毕后并且退出
while(cur_thread > 0) {
ProducterWait();
}
ThreadUnLock();
}
};
threadpool.cpp
#include "threadpool.hpp"
int main()
{
MyTask task[10];
int i;
MyThreadPool pool;
for (i = 0; i < 10; i++) {
task[i].SetData(i);
pool.AddTaskToPool(&task[i]);
} p
ool.StopThreadPool();
return 0;
}
内容总结
以上是互联网集市为您收集整理的Linux线程(六)全部内容,希望文章能够帮你解决Linux线程(六)所遇到的程序开发问题。 如果觉得互联网集市技术教程内容还不错,欢迎将互联网集市网站推荐给程序员好友。
内容备注
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 gblab@vip.qq.com 举报,一经查实,本站将立刻删除。
内容手机端
扫描二维码推送至手机访问。