linux網絡編程(四)線程池
- 為什么會有線程池?
- 實現簡單的線程池
為什么會有線程池?
大多數的服務器可能都有這樣一種情況,就是會在單位時間內接收到大量客戶端請求,我們可以采取接受到客戶端請求創建一個線程的方式來執行,雖然線程對于進程來說開銷已經很低了,但是大量的請求,也會占用巨量cpu資源。那么我們能不能采取一種方法來解決這個問題呢。線程池就出現了,假設我們會創建5個空閑線程,我們會將這些任務存入到隊列中,當我們有空閑線程時就來處理任務,這樣占用巨大cpu資源的情況是不是就能解決了呢。
實現簡單的線程池
#pragma once#include <stdio.h>
#include <stdlib.h>
/*
任務類:線程所要實現的功能在任務類中實現
*/
class Ctask
{
public:Ctask();~Ctask();void run();
private:};
#include "Ctask.h"Ctask::Ctask()
{}Ctask::~Ctask()
{
}void Ctask::run()
{printf("do task !\n");}
線程池需要一個鎖,為什么呢?其實很簡單,多個線程同時調用的,會出現競爭的情況,那么使用鎖,可以防止這種情況。
同時還有一個問題,當任務來的時候,我們怎么讓線程知道,這時我們所采用的就是條件變量,當任務來的時候,通知線程來執行
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <strings.h>
#include <string.h>
#include <ctype.h>
#include <signal.h>
#include <arpa/inet.h>
#include <sys/wait.h>
#include <time.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <iostream>
#include <stack>
#include <queue>
#include "Ctask.h"
using namespace std;typedef struct thread_pool
{pthread_cond_t cond;pthread_mutex_t mutex;int idel; //當前空閑線程的數量,如果空閑線程>0,喚醒線程,如果沒有,創建新線程int count;//當前有多少線程queue<Ctask*>task;
}THREAD_POOL_T;
class Threadpool
{
public:THREAD_POOL_T pool;//線程池初始化Threadpool();~Threadpool();void thread_pool_add_task(Ctask* t);
private:};
#include "Threadpool.h"void* start_routine(void* arg)
{THREAD_POOL_T* pool = (THREAD_POOL_T*)arg; //轉化while (1){//加鎖pthread_mutex_lock(&pool->mutex);pool->idel++;if (pool->task.empty())//如果任務隊列為空,條件變量等待加入任務{cout << "wait for wake .... =>" << pthread_self() << endl;pthread_cond_wait(&pool->cond,&pool->mutex);cout << "wake up .... =>" << pthread_self() << endl;}//取走任務pool->idel--;//從線程池里取走任務Ctask* t = pool->task.front();pool->task.pop();//解鎖pthread_mutex_unlock(&pool->mutex);printf("%d\n",pool->task.size());t->run();}}Threadpool::Threadpool()
{//初始化條件變量pthread_cond_init(&pool.cond,NULL);//初始化鎖pthread_mutex_init(&pool.mutex,NULL);pool.idel = 0;pool.count = 0;//默認創建三個線程for (int i = 0; i < 3; i++){pthread_t pid;pthread_create(&pid,NULL,start_routine,&pool);pool.count++;}}Threadpool::~Threadpool()
{}void Threadpool::thread_pool_add_task(Ctask* t)
{//printf("3\n");//往pool這個線程池結構體的隊列里面添加一個任務pthread_mutex_lock(&pool.mutex);pool.task.push(t);//把任務加到線程池的棧里面,相當于存起來//判斷有沒有空閑線程,如果有,就喚醒線程if (pool.idel > 0){pthread_cond_signal(&pool.cond);}else{pthread_t tid;pthread_create(&tid, NULL, start_routine, &pool);}pthread_mutex_unlock(&pool.mutex);}
#include <cstdio>
#include "Threadpool.h"int main()
{//創建一個線程池,5個線程//往線程池里面添加任務,線程會執行任務Threadpool* pool = new Threadpool();for (int i = 0; i < 10; i++){Ctask* t=new Ctask();pool->thread_pool_add_task(t);}while (1){}}