FTP文件管理项目(本地云)项目日报 测试端(五)线程及线程池

1.今日完成任务

线程池的书写

2.用到的线程函数

1.pthread_create函数:创建线程
头文件:#include
int pthread_create(pthread_t *thread, const pthread_attr_t *attr,
void *(*start_routine) (void *), void *arg);
pthread_t *thread:传递一个pthread_t变量地址进来,用于保存新线程的tid(线程ID)
const pthread_attr_t *attr:线程属性设置,如使用默认属性,则传NULL
void *(*start_routine) (void *):函数指针,指向新线程应该加载执行的函数模块
void *arg:指定线程将要加载调用的那个函数的参数
返回值:成功返回0,失败返回错误号。
2.pthread_self函数:获取调用线程tid
头文件:#include
pthread_t pthread_self(void);
3.pthread_exit函数:调用线程退出函数
void pthread_exit(void *retval);
void *retval:线程退出时传递出的参数,可以是退出值或地址,如是地址时,不能是线程内部申请的局部地址。
注意和exit函数的区别,任何线程里exit导致进程退出,其他线程
未工作结束,主控线程退出时不能return或exit。
4.pthread_join函数:阻塞退出,回收尸体
int pthread_join(pthread_t thread, void **retval);
pthread_t thread:回收线程的tid
void **retval:接收退出线程传递出的返回值
返回值:成功返回0,失败返回错误号
5.pthread_cancel函数:在进程内某个线程可以取消另一个线程。
int pthread_cancel(pthread_t thread);
被取消的线程,退出值,定义在Linux的pthread库中常数PTHREAD_CANCELED的值是-1。
可以在头文件pthread.h中找到它的定义:
#define PTHREAD_CANCELED ((void *) -1)
6.pthread_detach函数:自己杀自己然后自己收尸
int pthread_detach(pthread_t tid);
pthread_t tid:分离线程tid
返回值:成功返回0,失败返回错误号
但是线程也可以被置为detach状态,这样的线程一旦终止就立刻回收,它占用的所有资源,而不保留终止状态。不能对一个已经处于detach状态的线程调用pthread_join。
8.线程基类的封装

#ifndef BASETHREAD_H
#define BASETHREAD_H
#include 
#include 
#include 

class CBaseThread
{
public:
    CBaseThread();
    ~CBaseThread();
    void start();
    virtual int run() = 0;
    bool isRunning() const;
    pthread_t threadId() const;
protected:
    pthread_t m_tid;
    bool m_bRun;
private:
    static void * rontine(void *arg);
};

#endif // BASETHREAD_H
.cpp
#include "BaseThread.h"

CBaseThread::CBaseThread()
:m_tid(0), m_bRun(false)
{

}
CBaseThread::~CBaseThread()
{

}
void CBaseThread::start()
{
        if (m_bRun == false)
        {
                if( pthread_create(&m_tid,NULL,rontine,(void *)this) != 0)
                {
                        perror("create thread error : ");
                }

        }
}
bool CBaseThread::isRunning() const
{
        return m_bRun;
}
void * CBaseThread::rontine(void *arg)
{

        pthread_detach(pthread_self());
        CBaseThread *thr = (CBaseThread *)arg;
        thr->m_bRun = true;
        int ret = thr->run();
        thr->m_bRun = false;
        pthread_exit((void *)ret);
}


#ifndef _THREADPOOL_H_
#define _THREADPOOL_H_

#include 
#include 
#include 
#include 
#include 
#include 
#include 

using namespace std;

//任务基类,其他任务都是继承它
class CTask
{
public:
	CTask(){}
	~CTask(){}
	virtual int run()= 0;
};

//线程池类
class CThreadPool
{
public:  
	CThreadPool(int maxCount = 100, int waittime = 60);
	int start(int threadcount = 10);
	int addTask(CTask *task);					//把任务添加到线程池中  
	int destroy();									//停止线程池
protected:
	static void* rontine(void * threadData);	//新线程的线程函数
private:
	void createThread();
	void lock();							//互斥量上锁
	void unlock();						//互斥量解锁
	int  wait();							//设置条件变量永久等待
	int  waittime(int sec);				//设置条件变量等待时间
	int  signal();						//发送信号
	int  broadcast();					//广播所有线程信号
	list m_taskList;				//任务列表
	pthread_mutex_t m_mutex;				//线程同步锁  
	pthread_cond_t m_cond;				//线程同步的条件变量
	bool m_bStop;						//线程停止标识
	int m_maxCount;						//线程的最大限制
	int m_waitCount;						//线程等待数
	int m_count;
	int m_waittime;
}; 
.cpp
#include "ThreadPool.h"

CThreadPool::CThreadPool(int maxCount, int waittime)  
{
	//设置最大线程数量
	m_maxCount  = maxCount;
	if (m_maxCount <= 0)
	{
		printf("[threadpool] thread max count error \n");
		exit(-1);
	}
	m_bStop		= false;
	m_waitCount = 0;
	m_count     = 0;
	m_waittime  = waittime;
	if (m_waittime <= 0)
	{
		printf("[threadpool] thread wait time error \n");
		exit(-1);
	}

	//初始化互斥量和条件变量
	pthread_mutex_init(&m_mutex, NULL);
	pthread_cond_init(&m_cond, NULL);
}

void CThreadPool::lock()
{
	//互斥量加锁
	
	if( pthread_mutex_lock(&m_mutex) != 0)
		perror("Lock error");
		//printf("L\n");
}

void CThreadPool::unlock()
{
	//互斥量解锁
	if( pthread_mutex_unlock(&m_mutex) != 0)
		perror("Unlock error");
	//printf("U\n");
}

int CThreadPool::wait()
{
	//设置添加变量等待
	//条件变量等待一定要在互斥锁区域内
	//lock();
	int ret = pthread_cond_wait(&m_cond, &m_mutex);
	//unlock();
	return ret;
}

int CThreadPool::waittime(int sec)
{
	//设置添加变量等待时间sec秒
	//条件变量等待一定要在互斥锁区域内
	//lock();
	struct timespec abstime;
	clock_gettime(CLOCK_REALTIME, &abstime);
	abstime.tv_sec += sec;
	int ret = pthread_cond_timedwait(&m_cond, &m_mutex, &abstime);
	//unlock();
	return ret;
}

int CThreadPool::signal()
{
	//发送条件变量信号
	return pthread_cond_signal(&m_cond);
}

int CThreadPool::broadcast()
{
	//广播条件变量信号
	return pthread_cond_broadcast(&m_cond);
}

int CThreadPool::start(int threadcount)
{
	if (threadcount <= 0)
	{
		printf("create thread count error\n");
		return -1;
	}

	threadcount = threadcount > m_maxCount ? m_maxCount : threadcount;

	lock();
	for (int i = 0; i < threadcount; i++)
		createThread();
	unlock();

	return 0;
}

void CThreadPool::createThread()
{
	//如果没有线程等待,并且线程的数量小于最大数,线程池不是停止
	if( m_count < m_maxCount && !m_bStop)
	{
		pthread_t tid = 0;  
		if( pthread_create(&tid, NULL, rontine, (void *)this) != 0)
		{
			perror("create thread error : ");
			//printf("current thread count %d max count %d\n", m_count, m_maxCount);
		}
		else
		{
			//printf("create thread id 0x%x\n",tid);
			m_count++;
		}
	}
}
 
//线程池线程运行函数
void* CThreadPool::rontine(void * threadData)  
{
	CThreadPool *pool = (CThreadPool *)threadData;

	while(1)
	{
		pool->lock();
		if (pool->m_bStop)
		{
			//线程池停止,线程退出,线程id从列表中移出
			break;
		}
		
		//如果没有任务,线程进入等待状态
		if (pool->m_taskList.size() == 0)
		{

			//等待的线程计数加一
			pool->m_waitCount++;
			int ret = pool->waittime(pool->m_waittime);

			//线程被唤醒,等待的线程计数减一
			pool->m_waitCount--;

			//判断是否是等待超时
			if (ret == ETIMEDOUT)
			{
				break;
			}
		}
		//如果有任务
		if (pool->m_taskList.size() > 0)
		{
			//获取任务			
			CTask *task = pool->m_taskList.front();
			pool->m_taskList.pop_front();
			//cout << "current task count : " << pool->m_taskList.size() << endl;
			pool->unlock();

			//要在运行任务之前解锁,以免锁被占用
			task->run();
            delete task;
			//pool->lock();
			
		}
		else
		{
			pool->unlock();
		}
	}
	//cout<< "thread exit" << endl;
	pool->m_count--;
	//printf("thread count %d task count %d\n", pool->m_count, pool->m_taskList.size());

	if (pool->m_count <= 0 && pool->m_bStop )
	{
		pool->signal();
	}

	pool->unlock();

	pthread_exit(NULL);
	//return NULL;
}

int CThreadPool::addTask(CTask *task)  
{
	//判断线程池是否已经停止
	lock();
	if ( !m_bStop )
	{
		m_taskList.push_back(task);
	}
	else
	{
		unlock();
		return -1;
	}

	//如果有线程在等待,发送信号唤醒一个线程去处理
	if (m_waitCount > 0)
	{
		signal();
	}
	else
	{
		createThread();
	}

	unlock();
	return 0;  
}

int CThreadPool::destroy()
{
	//设置退出标识为true
	m_bStop = true;

	//清空任务列表
	lock();
	list::iterator it = m_taskList.begin();
	for (; it != m_taskList.end(); it++)
	{
		CTask *task = *it;
		delete task;
		task = NULL;
	}
	m_taskList.clear();
	unlock();

	//广播信号,然后等待的线程解除阻塞
	
	broadcast();

	//sleep(1);

	wait();

	return 0;
}

你可能感兴趣的:(Linux,线程)