3,882
社区成员




#include "lib/thread.h"
#include <cstdio>
#include <unistd.h>
class MyThread : public Thread
{
public:
MyThread(){ }
~MyThread(){ }
private:
virtual void run(){
for(int i=0; i<5000; i++)
printf("thread:%lu to print\n", MyThread::currentThreadId());
}
};
int main()
{
MyThread thread1, thread2;
thread1.start();
thread2.start();
//thread1.terminate();
//两个线程都可以正常开始工作,但下面这里理论上的效果应该是任意一个线程结束之后结束进程,但不知为什么会在一个线程调用完cleanup()之后main()一直死循环在那里。
while(!thread1.isFinished() and !thread2.isFinished());
printf("main(): process over.\n");
return 0;
}
#ifndef __THREAD_H_
#define __THREAD_H_
#include <pthread.h>
#include "mutex.h"
class Thread
{
public:
static pthread_t currentThreadId();
static void* thread_func(void* arg);
static void cleanup(void* arg);
Thread();
virtual ~Thread();
bool isFinished() const {
return _finished;
}
bool isRunning() const {
return _running;
}
void setStackSize(unsigned stackSize){
if(_running) return;
_stackSize = stackSize;
}
unsigned getStackSize() const {
return _stackSize;
}
void join();
void start();
void terminate();
protected:
virtual void run() = 0;
private:
bool _running;
bool _finished;
bool _terminated;
unsigned _stackSize;
pthread_t _thread_id;
Mutex _mutex;
private:
Thread(const Thread&);
Thread& operator = (const Thread&);
Thread& operator = (const Thread&) const;
};
#endif
#include "thread.h"
#include <cstdio>
//#include "log.h"
//static func
void* Thread::thread_func(void* arg){
pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, NULL);
pthread_cleanup_push(Thread::cleanup, arg);
Thread* thread = reinterpret_cast<Thread*>(arg);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, NULL);
pthread_testcancel();
thread->run();
pthread_cleanup_pop(1);
return 0;
}
//static func
pthread_t Thread::currentThreadId(){
return pthread_self();
}
Thread::Thread():_running(false), _terminated(false), _finished(false), _thread_id(0), _stackSize(0){
}
Thread::~Thread(){
//..
}
void Thread::start() {
if(_running) return;
_running = true;
_finished = false;
_terminated = false;
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
if(_stackSize > 0){
int ret = pthread_attr_setstacksize(&attr, _stackSize);
if(ret){
_running = false;
_finished = false;
return;
}
}
int ret = pthread_create(&_thread_id, &attr, Thread::thread_func, this);
if(ret){
_running = false;
_finished = false;
_thread_id = 0;
printf("Thread::start(): fail to create pthread.\n");
}
pthread_attr_destroy(&attr);
}
void Thread::terminate() {
if(!_thread_id) return;
int code = pthread_cancel(_thread_id);
if(code){
// BLOG(ERROR, "Thread::terminate(): error.");
} else {
_terminated = true;
}
}
void Thread::cleanup(void* arg){
Thread* thread = reinterpret_cast<Thread*>(arg);
thread->_running = false;
thread->_finished = true;
thread->_terminated = false;
thread->_thread_id = 0;
printf("thread cleanup succeeded.\n");
}