Thrift TThread的使用
- #include <iostream>
- #include <thrift/concurrency/Thread.h>
- #include <thrift/concurrency/PlatformThreadFactory.h>
- #include <boost/shared_ptr.hpp>
- using namespace boost;
- using namespace apache::thrift::concurrency;
- class MyTask : public Runnable {
- public:
- MyTask() {}
- void run() {
- std::cout << "\t\t hello world" << std::endl;
- }
- };
- int main() {
- shared_ptr<MyTask> task(new MyTask());
- PosixThreadFactory threadFactory;
- threadFactory.setDetached(false);
- shared_ptr<Thread> thread = threadFactory.newThread(task);
- thread->start();
- thread->join();
- return 0;
- }
下面看看Thread的实现, 下面的demo只是写了一个Thread实现的基本思路:
- #include <boost/shared_ptr.hpp>
- #include <auto_ptr.h>
- #include <thread>
- #include <iostream>
- using namespace boost;
- class Runnable {
- public:
- virtual ~Runnable() {}
- virtual void run() = 0;
- };
- class Thread {
- public:
- static void* threadMain(void *);
- public:
- Thread(shared_ptr<Runnable> runnable) {
- runnable_ = runnable;
- }
- ~Thread() {
- try {
- thread_->join();
- } catch (...) {
- // We're really hosed.
- }
- }
- void start() {
- auto function = std::bind(threadMain, (void *)this);
- thread_ = std::auto_ptr<std::thread>(new std::thread(function));
- }
- void join() {
- thread_->join();
- }
- private:
- shared_ptr<Runnable> runnable_;
- std::auto_ptr<std::thread> thread_;
- };
- void *Thread::threadMain(void *arg) {
- Thread *thread = (Thread *)arg;
- thread->runnable_->run();
- return (void *)0;
- }
- class Task : public Runnable {
- public:
- void run() {
- std::cout << "Task is running..." << std::endl;
- }
- };
- int main() {
- boost::shared_ptr<Runnable> runnable(new Task());
- boost::shared_ptr<Thread> thread(new Thread(runnable));
- thread->start();
- thread->join();
- }
上面代码有什么问题呢?
我们知道我们通常用这样的方式创建一个Thread:
- boost::shared_ptr<Thread> thread(new Thread(runnable));
可是在start函数中:
- void start() {
- auto function = std::bind(threadMain, (void *)this);
- thread_ = std::auto_ptr<std::thread>(new std::thread(function));
- }
我们把this传到了threadMain函数中。为了安全起见,我们需要传递一个自身的智能指针,防止double free.
1. 添加自己的指针,避免循环引用,使用week_ptr
- class BoostThread {
- private:
- week_ptr<BoostThread> self_;
- public:
- void weakRef(shared_ptr<BoostThread> self) {
- assert(self.get() == this);
- self_ = weak_ptr<BoostThread>(self);
- }
2. newThread中,调用完构造函数后,调用weekRef传入自己。
- shared_ptr<Thread> newThread(shared_ptr<Runnable> runnable) const {
- shared_ptr<BoostThread> result = shared_ptr<BoostThread>(new BoostThread(detached_, runnable));
- result->weakRef(result);
- runnable->thread(result);
- return result;
- }
3. 在start函数中
- void start() {
- // Create reference
- shared_ptr<BoostThread>* selfRef = new shared_ptr<BoostThread>();
- *selfRef = self_.lock();
- thread_ = std::auto_ptr<boost::thread>(new boost::thread(boost::bind(threadMain, (void*)selfRef)));
- }
4. threadMain函数
- void* BoostThread::threadMain(void* arg) {
- shared_ptr<BoostThread> thread = *(shared_ptr<BoostThread>*)arg;
- delete reinterpret_cast<shared_ptr<BoostThread>*>(arg);
- thread->state_ = started;
- thread->runnable()->run();
- }
这个代码示例如下:
- #include <boost/shared_ptr.hpp>
- #include <boost/weak_ptr.hpp>
- #include <auto_ptr.h>
- #include <thread>
- #include <iostream>
- using namespace boost;
- using boost::shared_ptr;
- using boost::weak_ptr;
- class Runnable {
- public:
- virtual ~Runnable() {}
- virtual void run() = 0;
- };
- class Thread {
- private:
- weak_ptr<Thread> self_;
- shared_ptr<Runnable> runnable_;
- std::auto_ptr<std::thread> thread_;
- public:
- static void* threadMain(void *);
- public:
- Thread(shared_ptr<Runnable> runnable) {
- runnable_ = runnable;
- }
- ~Thread() {
- try {
- thread_->join();
- } catch (...) {
- // We're really hosed.
- }
- }
- void start() {
- shared_ptr<Thread> *selfRef = new shared_ptr<Thread>();
- *selfRef = self_.lock();
- auto function = std::bind(threadMain, (void *)(selfRef));
- thread_ = std::auto_ptr<std::thread>(new std::thread(function));
- }
- void join() {
- thread_->join();
- }
- void weakPtr(shared_ptr<Thread> self) {
- self_ = self;
- }
- };
- void *Thread::threadMain(void *arg) {
- shared_ptr<Thread> *p = (shared_ptr<Thread> *)arg;
- shared_ptr<Thread> thread = *p;
- delete p;
- thread->runnable_->run();
- return (void *)0;
- }
- class ThreadFactory {
- public:
- static shared_ptr<Thread> newThread(shared_ptr<Runnable> runnable) {
- shared_ptr<Thread> thread(new Thread(runnable));
- thread->weakPtr(thread);
- return thread;
- }
- };
- class Task : public Runnable {
- public:
- void run() {
- std::cout << "Task is running..." << std::endl;
- }
- };
- int main() {
- shared_ptr<Runnable> runnable(new Task());
- shared_ptr<Thread> thread = ThreadFactory::newThread(runnable);
- thread->start();
- thread->join();
- }
下面的代码展示了通过创建Helper(Agent)的方式传递本身的方法:
#include <iostream>
#include <thrift/concurrency/Thread.h>
#include <thrift/concurrency/PlatformThreadFactory.h>
#include <boost/shared_ptr.hpp>
#include <boost/make_shared.hpp>
using namespace boost;
using namespace apache::thrift::concurrency;
class ServerThread {
public:
ServerThread() : helper_(new Helper(this)), running_(false) {
}
void start() {
assert(!running_);
running_ = true;
PosixThreadFactory threadFactory;
threadFactory.setDetached(false);
thread_ = threadFactory.newThread(helper_);
thread_->start();
}
void run() {
std::cout << "serverThread Running..." << std::endl;
}
void stop() {
std::cout << "serverThread stopping..." << std::endl;
if (running_)
thread_->join();
}
~ServerThread() {
if (running_) {
try {
stop();
} catch (...) {
std::cout << "error shutting down server" << std::endl;
}
}
}
private:
class Helper : public Runnable {
public:
Helper(ServerThread *serverThread) : serverThread_(serverThread) {
}
void run() {
serverThread_->run();
}
private:
ServerThread *serverThread_;
};
bool running_;
boost::shared_ptr<Helper> helper_;
boost::shared_ptr<Thread> thread_;
};
int main()
{
shared_ptr<ServerThread> serverThread = boost::make_shared<ServerThread>();
serverThread->start();
return 0;
}
吐槽: CSDN的编辑空间糟透了。