您的位置:首页 > 其它

关于线程库pthread_cond_signal丢失的问题

2010-12-08 17:03 1326 查看
这两天写了一个关于C++的线程库,刚开始老是出现信号丢失的问题,百思不得其解。后来才发现原来要pthrea_cond_wait和pthread_cond_signal之间要用一个条件变量来控制。例如:while(count==0)pthread_cond_wait();count--;

在pthread_cond_signal处,要用if(count==0)pthread_cond_signal();count++.

下面是我写的线程池代码:

.h文件:

#ifndef __THREAD_POOL_FOR_INOTIFY__

#define __THREAD_POOL_FOR_INOTIFY__

#include <iostream>

#include <queue>

#include <pthread.h>

using namespace std;

typedef void* (*TASKFUN)(void* arg);

class Task{

public:

void SetData(void* data){

m_data=data;

}

void SetFun(TASKFUN myFun){

m_fun=myFun;

}

void run();

private:

void* m_data;

TASKFUN m_fun;

};

class ThreadItem;

class ThreadPool{

public:

ThreadPool(int ThreadNum);

int InitPool();

~ThreadPool();

int AddTask(Task* task);

protected:

friend class ThreadItem;

private:

int iMaxThread;

static pthread_mutex_t mutex;

pthread_mutexattr_t mutexattr;

pthread_condattr_t condattr;

static pthread_cond_t cond;

static int busyNums;

vector<ThreadItem*> Threadlist;

static queue<Task*> Worklist;

};

class ThreadItem{

public:

ThreadItem(){

busy=false;

stop=false;

pthread_create(&th_t, NULL,ThreadWork, NULL);

}

bool inline IsBusy(){return busy==true;}

void inline SetBusy(){busy = true;}

void inline SetIdle(){busy = false;};

void inline SetStop(){stop=true;}

static void* ThreadWork(void* Para);

pthread_t th_t;

~ThreadItem()

{

if(!stop)stop=true;

pthread_cond_signal(&(ThreadPool::cond));

cout<<"th_t:"<<th_t<<endl;

pthread_join(th_t, NULL);

}

private:

static bool busy;

static bool stop;

};

#endif

.cpp文件:

#include "ThreadPool.h"
void* ThreadWork(void* Para);
bool ThreadItem::stop;
pthread_mutex_t ThreadPool::mutex;
pthread_cond_t ThreadPool::cond;
bool ThreadItem::busy;
queue<Task*> ThreadPool::Worklist;
int ThreadPool::busyNums;
int globalCount=0;
void* ThreadItem::ThreadWork(void* Para)
{
int runflag=0;
(ThreadPool::busyNums)++;
while(!stop){
pthread_mutex_lock(&(ThreadPool::mutex));
while(globalCount==0)
pthread_cond_wait(&(ThreadPool::cond), &(ThreadPool::mutex));
globalCount--;
busy=true;
if(!(ThreadPool::Worklist).empty()){
runflag=1;
Task* task = (ThreadPool::Worklist).front();
(ThreadPool::Worklist).pop();
task->run();
delete task;
busy=false;
(ThreadPool::busyNums)>0?(ThreadPool::busyNums)--:0;
}
pthread_mutex_unlock(&(ThreadPool::mutex));
}
return (NULL);
}
void Task::run()
{
m_fun(m_data);
}
ThreadPool::ThreadPool(int ThreadNum)
{
iMaxThread=ThreadNum;
busyNums=0;
}
ThreadPool::~ThreadPool()
{
vector<ThreadItem*>::iterator iterator_list;
while(busyNums>0){
cout<<"there is some thread working.../n";
usleep(300*1000);
}
for(iterator_list=Threadlist.begin(); iterator_list!=Threadlist.end(); ){
delete (*iterator_list);
iterator_list=Threadlist.erase(iterator_list);
}
while(!Worklist.empty()){
Worklist.pop();
}
pthread_mutexattr_destroy(&mutexattr);
pthread_mutex_destroy(&mutex);
pthread_condattr_destroy(&condattr);
pthread_cond_destroy(&cond);
}
int ThreadPool::AddTask(Task* task)
{
if(!task)return -1;
pthread_mutex_lock(&mutex);
Worklist.push(task);
if(globalCount==0)
pthread_cond_signal(&cond);
globalCount++;
pthread_mutex_unlock(&mutex);
return 0;
}
int ThreadPool::InitPool()
{
if(iMaxThread<=0)return -1;
pthread_mutexattr_init(&mutexattr);
pthread_mutexattr_settype(&mutexattr, PTHREAD_MUTEX_RECURSIVE_NP);
pthread_mutex_init(&mutex, &mutexattr);
pthread_condattr_init(&condattr);
pthread_cond_init(&cond, &condattr);
Threadlist.resize(iMaxThread);
int i=0;
for(i=0; i< iMaxThread; i++)
{
ThreadItem* Item= new ThreadItem;
Threadlist.push_back(Item);
}
while(busyNums!=iMaxThread){
cout<<"init pool now, please wait.../n";
usleep(300*1000);
}
busyNums=0;
globalCount=0;
return 0;
}
void* myfun(void*arg)
{
int* p = (int*)arg;
cout<<"this is the "<<*p<<"th task!/n";
delete p;
//sleep(1);
cout<<"my fun returned.../n";
return NULL;
}
int main()
{
ThreadPool pool(100);
if(pool.InitPool()<0){
cout<<"init pool error!/n";
return 0;
}
int i=0;
for(i=0;i<100; i++){
int*p = new int;
*p = i;
Task* pTask=new Task;
pTask->SetData(p);
pTask->SetFun(myfun);
cout<<"add:"<<i<<" task/n";
pool.AddTask(pTask);
}
while(1){
cout<<"haa"<<endl;;
sleep(1);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: