#pragma once
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <unistd.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
class CThread
{
public:
typedef void(*threadFun_t)(void* arg);
void EXIT_ERROR(const char* msg);
CThread(const threadFun_t& threadRoutine, void* arg);
void start();
void join();
~CThread();
static void* threadGuide(void* arg);
pthread_t getThreadId(void);
private:
bool m_isRunning; //该线程是否运行
pthread_t m_threadId; //线程ID
threadFun_t m_threadRoutine; //线程入口函数
void* m_threadArg; //线程入口函数参数
};
#include "CPthread.h"
#include <iostream>
using namespace std;
void CThread::EXIT_ERROR(const char* msg)
{
perror(msg);
exit(-1);
}
CThread::CThread(const threadFun_t& threadRoutine, void* arg)
{
m_isRunning = false;
m_threadId = 0;
m_threadRoutine = threadRoutine;
m_threadArg = arg;
}
void CThread::start()
{
pthread_attr_t attr;
if (!pthread_attr_init(&attr)) {
//设置线程的继承:新的线程继承策略和参数来自于schedpolicy和schedparam属性中显式设置的调度信息!
if ((!pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED))) {
//设置线程的调度策略:其他调度策略(轮转法,先进先出)
if (!pthread_attr_setschedpolicy(&attr, SCHED_OTHER)) {
//设置线程的作用域:系统级调用(进程内竞争调用)
if (!pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM)) {}
else {
EXIT_ERROR("set thread scope failed");
}
}
else {
EXIT_ERROR("set thread policy failed");
}
}
else {
EXIT_ERROR("set thread herit failed");
}
}
else {
EXIT_ERROR("attr init failed");
}
if ((!pthread_create(&m_threadId, &attr, threadGuide, this))) {}
else {
EXIT_ERROR("thread create failed");
}
m_isRunning = true;
}
void CThread::join()
{
if (m_isRunning) {
if (!pthread_join(m_threadId, NULL)) {}
else {
perror("pthread join failed");
}
}
m_isRunning = false;
}
CThread::~CThread()
{
//如果线程正在执行,则分离此线程.为回收资源
if (m_isRunning) {
if (!pthread_detach(m_threadId)) {}
else {
EXIT_ERROR("thread detach failed");
}
}
}
void* CThread::threadGuide(void* arg)
{
CThread* p = static_cast<CThread*>(arg);
p->m_threadRoutine(p->m_threadArg);
return NULL;
}
pthread_t CThread::getThreadId(void)
{
return m_threadId;
}
#include "CThreadPool.h"
#include <sys/types.h>
#include <signal.h>
CThraedPool::CThraedPool(size_t tasksSize, size_t threadsSize)
{
m_tasksSize = tasksSize;
m_threadsSize = threadsSize;
m_waitCount = threadsSize;
m_threadsMax = MAX_THREADNUM;
m_isQuit = false;
pthread_mutex_init(&m_mutex, NULL);
pthread_cond_init(&m_cond, NULL);
//signal(SIGINT, CThraedPool::pthreadfun);
}
void CThraedPool::start()
{
m_isQuit = false;
m_threads.reserve(m_threadsSize);
for (size_t i = 0; i < m_threadsSize; i++)
{
m_threads.push_back(new CThread(threadRoutine, (void*)this));
m_threads[i]->start(); //开始创建线程
}
}
void CThraedPool::stop()
{
pthread_mutex_lock(&m_mutex);
m_isQuit = true;
pthread_cond_broadcast(&m_cond);//子线程有可能在忙,有可能在等
for (int i = m_threadsSize - 1; i >= 0; i--)
{
m_threads[i]->join();
delete(m_threads[i]);
m_threads.pop_back();
}
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_cond);
pthread_mutex_lock(&m_mutex);
printf("threadpool quiting...\n");
}
void CThraedPool::addTask(Task task)
{
//一请求一线程
cout << "add a task......" << endl;
if (m_threadsSize < m_threadsMax && m_waitCount == 0)
{
pthread_mutex_lock(&m_mutex);
m_threads.push_back(new CThread(threadRoutine, (void*)this));
m_tasksqueue.push(task);
pthread_mutex_unlock(&m_mutex);
m_threads[m_threads.size() - 1]->start();
m_threadsSize++;
}
else
{
pthread_mutex_lock(&m_mutex);
m_tasksqueue.push(task);
pthread_mutex_unlock(&m_mutex);
}
m_tasksSize++;
pthread_cond_signal(&m_cond);
}
int CThraedPool::getTaskCount()
{
return this->m_workqueue.size();
}
void CThraedPool::pthreadfun(int no)
{
cout << "%%%%%%%%%" << no << endl;
}
CThraedPool::~CThraedPool()
{
if (!m_isQuit)
{
stop();
}
}
void CThraedPool::threadRoutine(void* arg)
{
CThraedPool* p = static_cast<CThraedPool*>(arg);
while (!(p->m_isQuit))
{
Task task = p->take();
if (task)
{
task();
pthread_mutex_lock(&(p->m_mutex));
p->m_workqueue.erase(pthread_self()); //从工作队列中删除
p->m_tasksSize--;
pthread_mutex_unlock(&(p->m_mutex));
}
}
pthread_mutex_lock(&(p->m_mutex));
p->m_threadsSize--;
pthread_mutex_unlock(&(p->m_mutex));
if (p->m_threadsSize == 0)
{
pthread_cond_signal(&p->m_cond);
}
printf("a thread quiting...\n");
return;
}
Task CThraedPool::take()
{
if (m_tasksqueue.empty() && !m_isQuit) //任务队列为空,一直睡眠
{
pthread_mutex_lock(&m_mutex);
m_waitCount++;
//cout << "waiting......" << endl;
pthread_cond_wait(&m_cond, &m_mutex);
m_waitCount--;
//cout << "wakeup......" << endl;
pthread_mutex_unlock(&m_mutex);
}
else if (!m_tasksqueue.empty() && !m_isQuit)
{
Task task = m_tasksqueue.front();
pthread_mutex_lock(&(m_mutex));
m_tasksqueue.pop();
m_workqueue.insert(pair<pthread_t, Task>(pthread_self(), task)); //移入工作队列
pthread_mutex_unlock(&m_mutex);
return task;
}
return NULL;
}