一个项目中需要用到pthread,发现把它封装到类中使用起来更加的方便。
这里保存了实例代码,以备以后使用。
头文件中定义了ThreadBase类,它包含了线程基本的一些接口,start() join() 和quit()
run()为接口函数,使派生类可以实现自己的工作函数。
thread_base.h
#ifndef _THREAD_BASE_H_ #define _THREAD_BASE_H_ #include <pthread.h> #include <iostream> #include <signal.h> using namespace std; class ThreadBase { private: pthread_t m_tid; bool m_isAlive; private: static void* start_func(void* arg); public: int start(); int join(); int quit(); pthread_t getTid(); bool isAlive(); virtual void run() = 0; virtual ~ThreadBase(); }; #endif
thread_base.cpp, 在析构函数中会通过thread_kill向线程发送信号,终止正在运行的线程。
这里并没有采用pthread_cancle的方式。
#include "thread_base.h" void* ThreadBase::start_func(void* arg) { ThreadBase *ptr = (ThreadBase*) arg; ptr->run(); return NULL; } int ThreadBase::start() { cout << "Start a new thread" << endl; if (pthread_create(&m_tid, NULL, start_func, (void*)this) != 0) { cout << "Start a new thread failed!" << endl; return -1; } cout << "Start a new thread success! tid="<< m_tid << endl; m_isAlive = true; return 0; } int ThreadBase::join() { int ret = -1; cout << "Join the thread tid=" << m_tid <<endl; ret = pthread_join(m_tid, NULL); if (ret != 0) cout << "Join the thread fail tid=" << m_tid <<endl; else cout << "Join the thread success tid=" << m_tid <<endl; return ret; } int ThreadBase::quit() { cout << "Quit the thread tid=" << m_tid <<endl; m_isAlive = false; return 0; } pthread_t ThreadBase::getTid() { return m_tid; } bool ThreadBase::isAlive() { return m_isAlive; } ThreadBase::~ThreadBase() { cout << "~ThreadBase tid="<< m_tid << endl; if (m_isAlive) { cout << "Kill the thread tid= "<< m_tid << endl; pthread_kill(m_tid, 0); } }
test.cpp是一个测试文件,它会创建3个线程,前两个以正常方式结束,第3个会在析构函数中结束线程。
#include "thread_base.h" #include "unistd.h" class ThreadTest1 : public ThreadBase { public: void run(); }; void ThreadTest1::run() { while (isAlive() == true) { cout << "Thread test 1 tid="<< getTid() << endl; sleep(1); } } class ThreadTest2 : public ThreadBase { public: void run(); }; void ThreadTest2::run() { while (isAlive() == true) { cout << "Thread test 2 tid="<< getTid() << endl; sleep(1); } } class ThreadTest3 : public ThreadBase { public: void run(); }; void ThreadTest3::run() { while (isAlive() == true) { cout << "Thread test 3 tid="<< getTid() << endl; sleep(1); } } int main() { ThreadBase *test1 = new ThreadTest1(); ThreadBase *test2 = new ThreadTest2(); ThreadBase *test3 = new ThreadTest3(); test1->start(); test2->start(); test3->start(); sleep(10); test1->quit(); test2->quit(); test1->join(); test2->join(); delete test1; delete test2; delete test3; return 0; }
make file
CC = g++ RM = rm CFLAGS = -O2 -lpthread OBJSDIR = .objs #VPATH = . OBJS = thread_base.o test.o TARGET = test $(OBJSDIR): mkdir -p ./$@ $(TARGET):$(OBJSDIR) $(OBJS) $(CC) -o $(TARGET) $(OBJSDIR)/*.o $(CFLAGS) $(OBJS): %.o:%.cpp $(CC) -c $(CFLAGS) $< -o $(OBJSDIR)/$@ clean: -$(RM) $(TARGET) -$(RM) $(OBJSDIR)/*.o
当然如果需要还可以在基类中添加更多的功能,比如给线程设置一个逻辑的名字,添加线程对应的队列(类似 TLS)等方式。