C++实现线程池 .

C++实现线程池。

          欢迎转载,转载请注明原出处:http://blog.csdn.net/ithzhang/article/details/9020283

           代码地址:https://github.com/ithzhang/ThreadpoolLib.git

本文介绍的线程池采用C++语言,在windows平台下实现。此版本为Version 1.0,以后还会推出功能更完备的后续版本。本着技术分享的精神写作本文同时公布源代码。欢迎大家指出该线程池存在的问题并对当前性能进行讨论。

   

 

适用场景:

 

   1.需要大量的线程来完成任务,且完成任务的时间比较短。

   2.对性能要求苛刻的应用,比如要求服务器迅速相应客户请求。

   3.接受突发性的大量请求,但不至于使服务器因此产生大量线程的应用。

不适合在以下场景下使用:

 

   1.可能会长时间运行的任务。

   2.具有良好的优先级控制。(本线程池仅仅实现了简单的优先级控制,有两种优先级:普通级和高级)。

 

 

使用到的数据结构:

 

   任务队列:任务缓冲区,用于存储要执行任务的队列。可以调用线程池成员函数向该队列中增加任务。

 

   空闲线程堆栈:用于存储空闲线程。空闲线程堆栈中会被压入指定数量的线程类对象指针。线程对象个数等于创建线程时初始线程个数。

 

   活动线程链表:用以存储当前正在执行任务的线程。当有任务到来时,线程会从空闲堆栈转移到活动链表中。任务完成,且任务队列中没有任务时,会从活动链表转移到空闲堆栈中。本文中我称其为线程状态转换。

 

调度机制:



   1.向任务队列添加任务后,会检查此时空闲线程堆栈中是否有空闲线程,如有则从任务队列队首取出任务执行。

   2.当线程执行完当前任务,准备转移到空闲堆栈时,也会检查当前任务队列是否为空。若不为空,则继续取出任务执行。否则,转换到空闲线程堆栈。

除上述两种调度机制外,没有采用其他机制。

 

在创建线程池时会指定一个初始线程个数。此处我采取的是:一次性创建用户指定的线程,并加入到空闲线程堆栈。以后这个数量无法更改,且不会随着任务的多寡而增添或减少。

 

所有处于空闲队列中的线程都由于等待事件对象触发而处于阻塞态。等待事件对象成功的线程会进入到活动线程链表中。

 

使用到的类:

 

  CTask类:任务基类。每个任务应继承自此类,并实现taskProc成员函数。

 

  CMyThread类:工作线程类。每个类管理一个线程。同时关联一个任务类对象。

 

  CThreadPool类:线程池类,用以创建并管理线程池,同时实现对线程池内线程的调度。

 

  CMyStack类:空闲线程堆栈,用以存储空闲的工作线程。

 

  CMyList类:活动线程队列。用以存储目前正在执行任务的线程。

 

  CTaskQueue类:任务队列。用以存储要执行的任务。

 

  CMyMutex类:互斥类。用于实现线程互斥访问。CMyStack,CMyList和CMyQueue内部都使用了CMyMutex类。它们是线程安全的。

 

MyThread类和CThreadPool类为核心类。其余为辅助类。

 

 

CTask类

 

   CTask是任务基类,所以非常简单,仅仅提供接口。

其声明如下:

[cpp] view plaincopyprint?

  1. class CTask  
  2. {  
  3. public:  
  4.     CTask(int id);  
  5.     ~CTask(void);  
  6. public:  
  7.     virtual void taskProc()=0;  
  8.     bool getID();  
  9. private:  
  10.     int m_ID;  
  11. };  
class CTask
{
public:
	CTask(int id);
	~CTask(void);
public:
	virtual void taskProc()=0;
	bool getID();
private:
	int m_ID;
};

具体的任务类应继承自此基类,并实现taskProc函数。在该函数实现需要线程池执行的任务。

如:

[cpp] view plaincopyprint?

  1. //TestTask.h   
  2. #include "task.h"   
  3. class CTestTask :  
  4.     public CTask  
  5. {  
  6. public:  
  7.     CTestTask(int id);  
  8.     ~CTestTask(void);  
  9. public:  
  10.     virtual void taskProc();  
  11. };  
  12. //TestTask.cpp   
  13. #include "TestTask.h"   
  14. CTestTask::CTestTask(int id)  
  15.     :CTask(id)  
  16. {  
  17. }  
  18. CTestTask::~CTestTask(void)  
  19. {  
  20. }  
  21. void CTestTask::taskProc()  
  22. {  
  23.     //模拟任务。   
  24.     for(int i=0;i<10000;i++)  
  25.     {  
  26.         for(int j=0;j<10000;j++)  
  27.         {  
  28.             int temp=1;  
  29.             temp++;  
  30.         }  
  31.     }  
  32. }  
//TestTask.h
#include "task.h"
class CTestTask :
	public CTask
{
public:
	CTestTask(int id);
	~CTestTask(void);
public:
	virtual void taskProc();
};
//TestTask.cpp
#include "TestTask.h"
CTestTask::CTestTask(int id)
	:CTask(id)
{
}
CTestTask::~CTestTask(void)
{
}
void CTestTask::taskProc()
{
    //模拟任务。
	for(int i=0;i<10000;i++)
	{
		for(int j=0;j<10000;j++)
		{
			int temp=1;
			temp++;
		}
	}
}

 

CMyStack空闲线程堆栈类

 

CMyStack类用以存储空闲线程。内部采用stack实现。之所以采用栈来存储线程类对象,是因为:当一个线程执行完任务后,如果此时任务队列没有新任务,该线程就被压入到空闲线程栈。此后当有新任务到来时,栈顶元素,也就是刚刚被压入的线程会被弹出执行新任务。由于该线程是最近才被压入,其对应内存空间位于内存中的概率比其他线程的概率要大。这在一定程度上可以节省从系统页交换文件交换到物理内存的开销。

[cpp] view plaincopyprint?

  1. //MyStack.h   
  2. #pragma once   
  3. #include<stack>   
  4. #include "MyMutex.h"   
  5. class CMyThread ;  
  6. class CMyStack  
  7. {  
  8. public:  
  9.     CMyStack(void);  
  10.     ~CMyStack(void);  
  11. public:  
  12.     CMyThread* pop();  
  13.     bool push(CMyThread*);  
  14.     int getSize();  
  15.     bool isEmpty();  
  16.     bool clear();  
  17. private:  
  18.     std::stack<CMyThread*> m_stack;  
  19.     CMyMutex m_mutext;  
  20. };  
//MyStack.h
#pragma once
#include<stack>
#include "MyMutex.h"
class CMyThread ;
class CMyStack
{
public:
	CMyStack(void);
	~CMyStack(void);
public:
	CMyThread* pop();
	bool push(CMyThread*);
	int getSize();
	bool isEmpty();
	bool clear();
private:
	std::stack<CMyThread*> m_stack;
	CMyMutex m_mutext;
};

 

CMyList活动线程链表类

 

CMyList类用以存储正在执行任务的线程。内部采用list实现。活动线程在执行完任务后,可以被随时从活动链表中删除。之所以使用链表是因为在链表中删除某一元素的开销很小。

 

[cpp] view plaincopyprint?

  1. //MyList.h   
  2. #pragma once   
  3. #include <list>   
  4. #include "MyMutex.h"   
  5. class CMyThread;  
  6. class CMyList  
  7. {  
  8. public:  
  9.     CMyList(void);  
  10.     ~CMyList(void);  
  11. public:  
  12.     bool addThread(CMyThread*t);  
  13.     bool removeThread(CMyThread*t);  
  14.     int getSize();  
  15.     bool isEmpty();  
  16.     bool clear();  
  17. private:  
  18.     std::list<CMyThread*>m_list;  
  19.     CMyMutex m_mutex;  
  20. };  
//MyList.h
#pragma once
#include <list>
#include "MyMutex.h"
class CMyThread;
class CMyList
{
public:
	CMyList(void);
	~CMyList(void);
public:
	bool addThread(CMyThread*t);
	bool removeThread(CMyThread*t);
	int getSize();
	bool isEmpty();
	bool clear();
private:
	std::list<CMyThread*>m_list;
	CMyMutex m_mutex;
};

 

CMyQueue任务队列类

 

CMyQueue用以存储要执行的任务。内部采用双向队列实现。具有简单的优先级控制机制。当普通的优先级任务到来时,会正常入队。当高优先级任务到来时会插入到对首。线程池在调度时会简单的从队首取出任务并执行。

[cpp] view plaincopyprint?

  1. //MyQueue.h   
  2. #pragma once   
  3. #include<deque>   
  4. #include"MyMutex.h"   
  5. class CTask;  
  6. class CMyQueue  
  7. {  
  8. public:  
  9.     CMyQueue(void);  
  10.     ~CMyQueue(void);  
  11. public:  
  12.     CTask*pop();  
  13.     bool push(CTask*t);  
  14.     bool pushFront(CTask*t);、  
  15.     bool isEmpty();  
  16.     bool clear();  
  17. private:  
  18.     std::deque<CTask*>m_TaskQueue;  
  19.     CMyMutex m_mutex;  
  20. };  
//MyQueue.h
#pragma once
#include<deque>
#include"MyMutex.h"
class CTask;
class CMyQueue
{
public:
	CMyQueue(void);
	~CMyQueue(void);
public:
	CTask*pop();
	bool push(CTask*t);
	bool pushFront(CTask*t);、
	bool isEmpty();
	bool clear();
private:
	std::deque<CTask*>m_TaskQueue;
	CMyMutex m_mutex;
};

 

CMyMutex互斥类

 

CMyMutex类用于控制线程互斥访问。内部采用CRITICAL_SECTION实现 。在对活动线程链表、空闲线程堆栈、任务队列进行访问时都需要进行互斥访问控制。防止多线程同时访问导致的状态不一致的情况出现。

类声明如下:

[cpp] view plaincopyprint?

  1. //MyMutex.h   
  2. #pragma once   
  3. #include "windows.h"   
  4. class CMyMutex  
  5. {  
  6. public:  
  7.     CMyMutex(void);  
  8.     ~CMyMutex(void);  
  9. public:  
  10.     bool Lock();  
  11.     bool Unlock();  
  12. private:  
  13.     CRITICAL_SECTION m_cs;  
  14. };  
//MyMutex.h
#pragma once
#include "windows.h"
class CMyMutex
{
public:
	CMyMutex(void);
	~CMyMutex(void);
public:
	bool Lock();
	bool Unlock();
private:
	CRITICAL_SECTION m_cs;
};

 

CMyThread工作线程类

 

CMyThread类用于管理一个线程。该类内部有一个CTask*成员和一个事件对象。CTask*成员为与该线程关联的任务。调用assignTask可以为该线程设置对应的任务。

类声明如下:

[cpp] view plaincopyprint?

  1. //MyThread.h   
  2. #pragma once   
  3. #include "windows.h"   
  4. class CTask;  
  5. class CBaseThreadPool;  
  6. class CMyThread  
  7. {  
  8. public:  
  9.     CMyThread(CBaseThreadPool*threadPool);  
  10.     ~CMyThread(void);  
  11. public:  
  12.     bool startThread();  
  13.     bool suspendThread();  
  14.     bool resumeThread();  
  15.     bool assignTask(CTask*pTask);  
  16.     bool startTask();  
  17.     static DWORD WINAPI threadProc(LPVOID pParam);  
  18.     DWORD m_threadID;  
  19.     HANDLE m_hThread;  
  20. private:  
  21.     HANDLE m_hEvent;  
  22.     CTask*m_pTask;  
  23.     CBaseThreadPool*m_pThreadPool;    
  24. };  
//MyThread.h
#pragma once
#include "windows.h"
class CTask;
class CBaseThreadPool;
class CMyThread
{
public:
	CMyThread(CBaseThreadPool*threadPool);
	~CMyThread(void);
public:
	bool startThread();
	bool suspendThread();
	bool resumeThread();
	bool assignTask(CTask*pTask);
	bool startTask();
	static DWORD WINAPI threadProc(LPVOID pParam);
	DWORD m_threadID;
	HANDLE m_hThread;
private:
	HANDLE m_hEvent;
	CTask*m_pTask;
	CBaseThreadPool*m_pThreadPool;
};

 

startThread用于创建入口函数为threadProc的线程。在该线程内部会循环等待一个事件对象。当没有任务到来时,线程就会在该事件对象上挂起。当新任务到来,线程池会将该线程对应的事件对象触发,然后执行其对应的任务。

[cpp] view plaincopyprint?

  1. DWORD WINAPI CMyThread::threadProc( LPVOID pParam )  
  2. {  
  3.     CMyThread *pThread=(CMyThread*)pParam;  
  4.     while(!pThread->m_bIsExit)  
  5.     {  
  6.         DWORD ret=WaitForSingleObject(pThread->m_hEvent,INFINITE);  
  7.         if(ret==WAIT_OBJECT_0)  
  8.         {  
  9.             if(pThread->m_pTask)  
  10.             {  
  11.                 pThread->m_pTask->taskProc();、  
  12.                 delete pThread->m_pTask;  
  13.                 pThread->m_pTask=NULL;  
  14.                 pThread->m_pThreadPool->SwitchActiveThread(pThread);  
  15.             }  
  16.         }  
  17.     }  
  18.     return 0;  
  19. }  
DWORD WINAPI CMyThread::threadProc( LPVOID pParam )
{
	CMyThread *pThread=(CMyThread*)pParam;
	while(!pThread->m_bIsExit)
	{
 		DWORD ret=WaitForSingleObject(pThread->m_hEvent,INFINITE);
		if(ret==WAIT_OBJECT_0)
		{
			if(pThread->m_pTask)
			{
				pThread->m_pTask->taskProc();、
				delete pThread->m_pTask;
				pThread->m_pTask=NULL;
				pThread->m_pThreadPool->SwitchActiveThread(pThread);
			}
		}
	}
	return 0;
}

 

当任务执行完之后,线程内部会调用线程池的SwitchActiveThread成员函数,该函数用以将线程从活动状态转变为空闲态。也就是从活动线程链表转移到空闲线程栈中。同时线程继续等待事件对象触发。

在此函数内部,在转换之前会检查任务队列中是否还有任务,如果有任务,线程会继续从任务队列取出任务继续执行,而不会切换到空闲态。直到任务队列中没有任务时才会执行状态切换操作。

 

 

CMyThreadPool线程池类

 

 

任务队列、活动线程链表、空闲线程队列都作为线程池的成员变量,由线程池维护。

 

类声明如下:

[cpp] view plaincopyprint?

  1. //MyThreadPool.h   
  2. #pragma once   
  3. #include<list>   
  4. #include "MyMutex.h"   
  5. #include "MyStack.h"   
  6. #include "MyList.h"   
  7. #include"MyQueue.h"   
  8. class CMyThread;  
  9. class CTask;  
  10. enum PRIORITY  
  11. {  
  12.     NORMAL,  
  13.     HIGH  
  14. };  
  15. class CBaseThreadPool  
  16. {  
  17. public:  
  18.     virtual CMyThread* PopIdleThread()=0;  
  19.     virtual CTask*GetNewTask()=0;  
  20.     //virtual bool  ExecuteNewTask(CTask *task)=0;   
  21.     virtual bool SwitchActiveThread(CMyThread*)=0;  
  22. };  
  23. class CMyThreadPool:public CBaseThreadPool  
  24. {  
  25. public:  
  26.     CMyThreadPool(int num);  
  27.     ~CMyThreadPool(void);  
  28. public:  
  29.     virtual CMyThread* PopIdleThread();  
  30.     virtual bool SwitchActiveThread(CMyThread*);  
  31.     virtual CTask*GetNewTask();  
  32. public:  
  33.     //priority为优先级。高优先级的任务将被插入到队首。   
  34.     bool addTask(CTask*t,PRIORITY priority);  
  35.     bool start();//开始调度。   
  36.     bool destroyThreadPool();  
  37. private:  
  38.     int m_nThreadNum;  
  39.     bool m_bIsExit;  
  40.       
  41.     CMyStack m_IdleThreadStack;  
  42.     CMyList m_ActiveThreadList;  
  43.     CMyQueue m_TaskQueue;  
  44. };  
//MyThreadPool.h
#pragma once
#include<list>
#include "MyMutex.h"
#include "MyStack.h"
#include "MyList.h"
#include"MyQueue.h"
class CMyThread;
class CTask;
enum PRIORITY
{
	NORMAL,
	HIGH
};
class CBaseThreadPool
{
public:
	virtual CMyThread* PopIdleThread()=0;
	virtual CTask*GetNewTask()=0;
	//virtual bool  ExecuteNewTask(CTask *task)=0;
	virtual bool SwitchActiveThread(CMyThread*)=0;
};
class CMyThreadPool:public CBaseThreadPool
{
public:
	CMyThreadPool(int num);
	~CMyThreadPool(void);
public:
	virtual CMyThread* PopIdleThread();
	virtual bool SwitchActiveThread(CMyThread*);
	virtual CTask*GetNewTask();
public:
	//priority为优先级。高优先级的任务将被插入到队首。
	bool addTask(CTask*t,PRIORITY priority);
	bool start();//开始调度。
	bool destroyThreadPool();
private:
	int m_nThreadNum;
	bool m_bIsExit;

	CMyStack m_IdleThreadStack;
	CMyList m_ActiveThreadList;
	CMyQueue m_TaskQueue;
};

 

addTask函数用于向任务队列中添加任务。添加任务后,会检查空闲线程堆栈中是否为空,如不为空则弹出栈顶线程执行任务。

[cpp] view plaincopyprint?

  1. bool CMyThreadPool::addTask( CTask*t,PRIORITY priority )  
  2. {  
  3.     assert(t);  
  4.     if(!t||m_bIsExit)  
  5.         return false;     
  6.     CTask *task=NULL;  
  7.     if(priority==PRIORITY::NORMAL)  
  8.     {  
  9.         m_TaskQueue.push(t);//压入任务队列尾部。   
  10.     }  
  11.     else if(PRIORITY::HIGH)  
  12.     {  
  13.         m_TaskQueue.pushFront(t);//高优先级任务,压到队首。   
  14.     }  
  15.     if(!m_IdleThreadStack.isEmpty())//存在空闲线程。调用空闲线程处理任务。   
  16.     {  
  17.             task=m_TaskQueue.pop();//取出列头任务。   
  18.             if(task==NULL)  
  19.             {  
  20.                 //std::cout<<"任务取出出错。"<<std::endl;   
  21.                 return 0;  
  22.             }  
  23.             CMyThread*pThread=PopIdleThread();  
  24.             m_ActiveThreadList.addThread(pThread);//加入到活动链表。   
  25.             pThread->assignTask(task);//将任务与线程关联。   
  26.             pThread->startTask();//开始任务,内部对事件对象进行触发。   
  27.     }  
  28.       
  29. }  
bool CMyThreadPool::addTask( CTask*t,PRIORITY priority )
{
	assert(t);
	if(!t||m_bIsExit)
		return false;
	CTask *task=NULL;
	if(priority==PRIORITY::NORMAL)
	{
		m_TaskQueue.push(t);//压入任务队列尾部。
	}
	else if(PRIORITY::HIGH)
	{
		m_TaskQueue.pushFront(t);//高优先级任务,压到队首。
	}
	if(!m_IdleThreadStack.isEmpty())//存在空闲线程。调用空闲线程处理任务。
	{
			task=m_TaskQueue.pop();//取出列头任务。
			if(task==NULL)
			{
				//std::cout<<"任务取出出错。"<<std::endl;
				return 0;
			}
			CMyThread*pThread=PopIdleThread();
			m_ActiveThreadList.addThread(pThread);//加入到活动链表。
			pThread->assignTask(task);//将任务与线程关联。
			pThread->startTask();//开始任务,内部对事件对象进行触发。
	}

}

 

    switchActiveThread函数用以在线程结束任务之后,将自己切换到空闲态。在切换之前会检查任务队列是否有任务,如有任务,则取出继续执行。直到任务队列为空时,才将自己切换到空闲态。由各线程类对象调用。

[cpp] view plaincopyprint?

  1. bool CMyThreadPool::SwitchActiveThread( CMyThread*t)  
  2. {  
  3.     if(!m_TaskQueue.isEmpty())//任务队列不为空,继续取任务执行。   
  4.     {  
  5.         CTask *pTask=NULL;  
  6.         pTask=m_TaskQueue.pop();      
  7.         t->assignTask(pTask);  
  8.         t->startTask();    
  9.     }  
  10.     else//任务队列为空,该线程挂起。   
  11.     {  
  12.         m_ActiveThreadList.removeThread(t);  
  13.         m_IdleThreadStack.push(t);  
  14.     }  
  15.     return true;  
  16. }  
bool CMyThreadPool::SwitchActiveThread( CMyThread*t)
{
	if(!m_TaskQueue.isEmpty())//任务队列不为空,继续取任务执行。
	{
		CTask *pTask=NULL;
		pTask=m_TaskQueue.pop();
		t->assignTask(pTask);
		t->startTask();
	}
 	else//任务队列为空,该线程挂起。
	{
		m_ActiveThreadList.removeThread(t);
		m_IdleThreadStack.push(t);
	}
	return true;
}

     代码地址:https://github.com/ithzhang/ThreadpoolLib.git

时间: 2024-10-24 14:56:27

C++实现线程池 .的相关文章

java concurrent包自带线程池和队列详细讲解

Java线程池使用说明一简介线程的使用在java中占有极其重要的地位,在jdk1.4极其之前的jdk版本中,关于线程池的使用是极其简陋的.在jdk1.5之后这一情况有了很大的改观.Jdk1.5之后加入了java.util.concurrent包,这个包中主要介绍java中线程以及线程池的使用.为我们在开发中处理线程的问题提供了非常大的帮助.二:线程池线程池的作用:线程池作用就是限制系统中执行线程的数量.     根据系统的环境情况,可以自动或手动设置线程数量,达到运行的最佳效果:少了浪费了系统资

Java线程池架构原理和源码解析(ThreadPoolExecutor)

在前面介绍JUC的文章中,提到了关于线程池Execotors的创建介绍,在文章:<java之JUC系列-外部Tools>中第一部分有详细的说明,请参阅: 文章中其实说明了外部的使用方式,但是没有说内部是如何实现的,为了加深对实现的理解,在使用中可以放心,我们这里将做源码解析以及反馈到原理上,Executors工具可以创建普通的线程池以及schedule调度任务的调度池,其实两者实现上还是有一些区别,但是理解了ThreadPoolExecutor,在看ScheduledThreadPoolExe

Java线程池 ExecutorService

本篇主要涉及到的是java.util.concurrent包中的ExecutorService.ExecutorService就是Java中对线程池的实现. 一.ExecutorService介绍 ExecutorService是Java中对线程池定义的一个接口,它java.util.concurrent包中,在这个接口中定义了和后台任务执行相关的方法: Java API对ExecutorService接口的实现有两个,所以这两个即是Java线程池具体实现类(详细了解这两个实现类,点击这里):

定制并发类(六)自定义在计划的线程池内运行的任务

声明:本文是< Java 7 Concurrency Cookbook>的第七章, 作者: Javier Fernández González 译者:郑玉婷 自定义在计划的线程池内运行的任务 计划的线程池是 Executor 框架的基本线程池的扩展,允许你定制一个计划来执行一段时间后需要被执行的任务. 它通过 ScheduledThreadPoolExecutor 类来实现,并允许运行以下这两种任务: Delayed 任务:这种任务在一段时间后仅执行一次. Periodic 任务:这种任务在延

Java多线程和线程池

版权声明:本文为博主原创文章,转载注明出处http://blog.csdn.net/u013142781 1.为什么要使用线程池 在Java中,如果每个请求到达就创建一个新线程,开销是相当大的.在实际使用中,服务器在创建和销毁线程上花费的时间和消耗的系统资源都相当大,甚至可能要比在处理实际的用户请求的时间和资源要多的多.除了创建和销毁线程的开销之外,活动的线程也需要消耗系统资源.如果在一个jvm里创建太多的线程,可能会使系统由于过度消耗内存或"切换过度"而导致系统资源不足.为了防止资源

Java基础-创建Java程序中的线程池

程序|创建 线程是Java的一大特性,它可以是给定的指令序列.给定的方法中定义的变量或者一些共享数据(类一级的变量).在Java中每个线程有自己的堆栈和程序计数器(PC),其中堆栈是用来跟踪线程的上下文(上下文是当线程执行到某处时,当前的局部变量的值),而程序计数器则用来跟踪当前线程正在执行的指令. 在通常情况下,一个线程不能访问另外一个线程的堆栈变量,而且这个线程必须处于如下状态之一: 1.排队状态(Ready),在用户创建了一个线程以后,这个线程不会立即运行.当线程中的方法start()被调

Java游戏起步:(一)线程与线程池

任何游戏都至少需要运行两个线程,主线程和GUI线程而线程池是一个管理运行线程的有用工具,下面的代码示范了一个线程池的实现方法~~************************************************(ThreadPool.java)import java.util.LinkedList; /** 线程池是一组线程,限制执行任务的线程数*/public class ThreadPool extends ThreadGroup { private boolean isAli

100行Java代码构建一个线程池

在现代的操作系统中,有一个很重要的概念――线程,几乎所有目前流行的操作系统都支持线程,线程来源于操作系统中进程的概念,进程有自己的虚拟地址空间以及正文段.数据段及堆栈,而且各自占有不同的系统资源(例如文件.环境变量等等).与此不同,线程不能单独存在,它依附于进程,只能由进程派生.如果一个进程派生出了两个线程,那这两个线程共享此进程的全局变量和代码段,但每个线程各拥有各自的堆栈,因此它们拥有各自的局部变量,线程在UNIX系统中还被进一步分为用户级线程(由进程自已来管理)和系统级线程(由操作系统的调

C#中使用多线程编程之线程池

编程|多线程 1.     引言 近来在研究C#多线程编程碰到了线程池的概念.不懂,我搜,于是在MSDN和CSDN上寻寻觅觅一番终于搞明白,"缘"来如此,安装本人理解修改后写下这篇文章,希望对后来者有所帮助.   2.     线程池的概念 可以使用线程池来根据应用程序的需要更为有效地利用多个线程.许多应用程序使用多个线程,但这些线程经常在休眠状态中耗费大量的时间来等待事件发生,编程者手动管理多个线程也是一件比较麻烦的事情.事实上,使用线程池就是为应用程序提供一个由系统管理的辅助线程池

C实现一个简单的线程池

//threadpool.h #ifndef __THREADPOOL_H__ #define __THREADPOOL_H__ #include <pthread.h> typedef void* (*task_fun)(void*); //用链表来维护等待任务 typedef struct threadtask { //任务的执行函数 task_fun task; //执行函数的参数 void* arg; //下一节点 struct threadtask* next; }THREAD_TA