上一个linux线程学习是不带锁的线程不安全形式,只要不用共享资源还是可以的,但实际工作中我们遇到的往往是需要保障线程的访问的.因此这里实现了一个简单的线程池,为线程池的实现提供思路。
Status类封装了环境变量与锁,作为一种状态保障线程的安全,并提供挂起,供Pthreadpool使用。
Eventloop类则用于管理方法,供Phtreadpool使用。
Pthreadpool封装了多线程,并结合Status类和Eventloop类,对外提供接口。
#ifndef STATUS_H
#define STATUS_H
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
class Status
{
public:
static Status *&construction()
{
if(NULL == obj)
{
obj = new Status();
}
return obj;
}
virtual ~Status();
virtual void lock();
virtual void unlock();
virtual void signal();
virtual void wait();
virtual int timedwait();
virtual void broadcast();
public:
static Status *obj;
private:
Status();
struct timeval _now;
struct timespec _timeout;
pthread_mutex_t _mutex;
pthread_cond_t _cond;
};
#define status (Status::obj->construction())
#define deletestatus (delete Status::obj)
#endif // STATUS_H
#ifndef EVENTLOOP_H
#define EVENTLOOP_H
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
typedef void *(*FUNC)(void *);
typedef struct Events
{
FUNC func;
void *param;
Events *next;
}Events;
class Eventloop
{
public:
static Eventloop *&construction()
{
if(NULL == obj)
{
obj = new Eventloop();
}
return obj;
}
~Eventloop();
void AddEvent(FUNC func, void *param);
void GetEvent(FUNC &func, void *¶m);
static Eventloop *obj;
private:
Eventloop();
unsigned int _eventnum;
Events *_begin;
Events *_end;
};
#define eventloop (Eventloop::obj->construction())
#endif // EVENTLOOP_H
#ifndef PTHREADPOOL_H
#define PTHREADPOOL_H
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include "Eventloop.h"
#define MAXPTHREAD 5
class Pthreadpool
{
friend void *callback(void *);
public:
~Pthreadpool();
static Pthreadpool *&construction()
{
if(NULL == obj)
{
obj = new Pthreadpool();
}
return obj;
}
int init();
int addFunc(FUNC func, void *param);
int run();
bool destory();
static Pthreadpool *obj;
private:
explicit Pthreadpool();
bool stop;
unsigned int _maxnum;
unsigned int _usable;
unsigned int _using;
pthread_t tid[MAXPTHREAD];
};
#define pthreadpool (Pthreadpool::obj->construction())
#endif // PTHREADPOOL_H
status.cpp:
#include "Status.h"
#include <sys/time.h>
#define TIMEWAIT 3
Status *Status::obj = NULL;
Status::Status()
{
pthread_mutex_init(&_mutex, NULL);
pthread_cond_init(&_cond, NULL);
}
Status::~Status()
{
pthread_mutex_destroy(&_mutex);
pthread_cond_destroy(&_cond);
}
void Status::lock()
{
pthread_mutex_lock(&_mutex);
}
void Status::unlock()
{
pthread_mutex_unlock(&_mutex);
}
void Status::signal()
{
pthread_cond_signal(&_cond);
}
void Status::wait()
{
pthread_cond_wait(&_cond, &_mutex);
}
int Status::timedwait()
{
_timeout.tv_sec = _now.tv_sec + TIMEWAIT;
_timeout.tv_nsec = _now.tv_usec;
gettimeofday(&_now, NULL);
int ret = pthread_cond_timedwait(&_cond, &_mutex, &_timeout);
return ret;
}
void Status::broadcast()
{
pthread_cond_broadcast(&_cond);
}
Eventloop.cpp:
#include "Eventloop.h"
#include "Status.h"
#include <string.h>
Eventloop *Eventloop::obj = NULL;
Eventloop::Eventloop()
{
_begin = _end = NULL;
_eventnum = 0;
}
Eventloop::~Eventloop()
{
Events *event;
if(NULL != _begin)
{
event = _begin;
_begin = _begin->next;
delete event;
}
_eventnum = 0;
}
void Eventloop::AddEvent(FUNC func,void *param)
{
if(NULL == func) return;
Events *event = new Events();
event->func = func;
event->param = param;
event->next = NULL;
if(NULL == _begin)
{
_begin = event;
}
else
{
_end->next = event;
}
_end = event;
++_eventnum;
printf("AddEvent : now _eventnum = %u\n",_eventnum);
}
void Eventloop::GetEvent(FUNC &func, void *¶m)
{
if(_begin == NULL) return;
printf("get Event!\n");
Events *event = _begin;
if(_begin == NULL) printf("what?!\n");
_begin = _begin->next;
func = event->func;
param = event->param;
delete event;
--_eventnum;
printf("DeleteEvent : now _eventnum = %u\n",_eventnum);
}
Pthreadpool.cpp:
#include "Pthreadpool.h"
#include "Status.h"
#include "Eventloop.h"
#include <errno.h>
#include <unistd.h>
Pthreadpool *Pthreadpool::obj = NULL;
Pthreadpool::Pthreadpool()
{
_maxnum = MAXPTHREAD;
}
void *callback(void *)
{
status->lock();
++pthreadpool->_usable;
status->unlock();
while(true)
{
FUNC func = NULL;
void *param = NULL;
status->lock();
eventloop->GetEvent(func, param);
if(NULL == func)
{
if(ETIMEDOUT == status->timedwait())
{
printf("tid[] = %lu timedwait.\n", pthread_self());
--pthreadpool->_maxnum;
--pthreadpool->_usable;
status->unlock();
if(pthreadpool->_maxnum == 0)
pthreadpool->stop = true;
break;
}
}
else
{
--pthreadpool->_usable;
++pthreadpool->_using;
}
status->unlock();
if(NULL != func)
{
func(param);
}
}
pthread_detach(pthread_self());
printf("tid[] = %lu detach and quit.\n", pthread_self());
if(pthreadpool->stop)
{
printf("I'm %lu,the last pthread,then I will send a signal.\n", pthread_self());
status->signal();
}
return NULL;
}
Pthreadpool::~Pthreadpool()
{
}
int Pthreadpool::init()
{
_usable = 0;
_using = 0;
stop = true;
return 0;
}
int Pthreadpool::addFunc(FUNC func, void *param)
{
status->lock();
eventloop->AddEvent(func, param);
status->unlock();
return 0;
}
int Pthreadpool::run()
{
stop = false;
unsigned int i = 0;
unsigned int num = _maxnum;
for(;i < num; ++i)
{
int fail = pthread_create(&tid[i], NULL, callback, NULL);
if(!fail)
{
printf("tid[%u] = %lu create successfully.\n", i, tid[i]);
}
else
{
printf("tid[%u] create failed.\n", i);
}
}
printf("_maxnum == %u\n", _maxnum);
printf("i == %u\n", i);
return 0;
}
bool Pthreadpool::destory()
{
if(pthreadpool->stop = true) return false;
status->lock();
printf("wait pthread over.\n");
status->wait();
printf("pthread over!\n");
status->unlock();
if(NULL != status)
{
deletestatus;
}
return true;
}
main.cpp:
#include <iostream>
#include "Eventloop.h"
#include "Pthreadpool.h"
#include <unistd.h>
using namespace std;
void *test1(void *ptr)
{
cout << "test:" << pthread_self() << " get ptr[10] and sleep 2s!" << endl;
int *arr = static_cast<int *>(ptr);
for(int i = 0; i < 10; ++i)
{
cout << arr[i] << "\t";
}
cout << endl;
sleep(2);
}
void *test2(void *ptr)
{
cout << "good good study day day up!" << endl;
cout << endl;
}
int main(int /*argc*/, char */*argv*/[])
{
printf("begin init!\n");
pthreadpool->init();
printf("end init!\n");
int ptr[10] = {1,3,5,7};
sleep(1);
printf("begin add!\n");
pthreadpool->addFunc(test1, &ptr);
pthreadpool->addFunc(test2, NULL);
printf("end add!\n");
sleep(1);
printf("begin run!\n");
pthreadpool->run();
printf("end run!\n");
sleep(1);
printf("begin destory!\n");
pthreadpool->destory();
printf("end destory!\n");
cout << "Hello World!" << endl;
return 0;
}
运行结果:
begin init!
end init!
begin add!
AddEvent : now _eventnum = 1
AddEvent : now _eventnum = 2
end add!
begin run!
tid[0] = 140676791965440 create successfully.
tid[1] = 140676783572736 create successfully.
get Event!
DeleteEvent : now _eventnum = 1
tid[2] = 140676775180032 create successfully.
test:140676791965440 get ptr[10] and sleep 2s!
get Event!
DeleteEvent : now _eventnum = 0
1 3 5 7 0 0 0 0 0 0
good good study day day up!tid[3] = 140676766787328 create successfully.
tid[] = 140676783572736 timedwait.
tid[] = 140676783572736 detach and quit.
tid[4] = 140676758394624 create successfully.
_maxnum == 4
i == 5
end run!
begin destory!
end destory!
Hello World!
转载请注明出处:https://blog.csdn.net/qq_39937902/article/details/79572502