一切从0开始,小小的手机网游服务端教程,其实我只是一个初学者。【四】Thread线程类和Mutex类
先写一个nocopy类吧,这样只要继承了这个类就可以防止子类复制,赋值。(类似于boost里面的noncopyable)
至少我是不希望线程类可以复制或者赋值吧。
//nocopy.h #ifndef __NOCOPY_H__ #define __NOCOPY_H__ class NoCopy { public: NoCopy(){} ~NoCopy(){} private: NoCopy(const NoCopy &); NoCopy &operator=(const NoCopy &); }; #endif
原理:父类的赋值和复制函数没有实现并且是私有的,因此子类在复制或赋值的时候会执行父类的复制或赋值构造函数(子类没有写赋值或复制函数),这时会出现编译错误,这是一个好技巧,很多时候很有用,可以减少工作量,要防止赋值或复制的时候只要继承它即可,so easy。
接下来写线程类Thread:
//thread.h #ifndef __THREAD_H__ #define __THREAD_H__ #include <pthread.h> #include <unistd.h> #include <sys/time.h> #include "nocopy.h" #include "runnable.h" class Thread: public NoCopy { public: Thread() { m_started = false; m_pid = 0; m_runner = NULL; } //开始 bool start(Runnable *runner) { m_runner = runner;m_runner->set_thread(this);
return (0 == pthread_create(&m_pid, NULL, _worker, this)); } //退出 void join() { if (m_started) { pthread_join(m_pid, NULL); } } //使线程睡眠x毫秒 static void sleep(int ms) { timeval tv; tv.tv_sec = ms / 1000; tv.tv_usec = (ms % 1000) * 1000; select(0, NULL, NULL, NULL, &tv); } pthread_t get_thread_id() const { return m_pid; } private: static void *_worker(void *arg) { Thread *thread = (Thread *)arg; thread->m_started = true; //TODO:这里没有做失败处理诶,lazy. thread->m_runner->init(); thread->m_runner->run(); thread->m_runner->retire(); return NULL; } private: bool m_started; pthread_t m_pid; Runnable *m_runner; }; #endif
为什么start函数中传了this呢?线程执行的函数必须是全局函数,所以只能执行类中得静态函数,而通过静态函数传入this,就可以操作对象中的成员了。
看到m_runner成员,在start函数执行的时候会对其进行赋值,线程启动_worker函数并会执行m_runner的init, run, retire函数,这样在前面一节的game_app.cpp中的
m_game_thread.start(&m_game);
就会启动一个新线程m_game。
写了那么多现在编译运行看看,程序跑起来了。显示game run, 只要按ctrl+c会结束程序运行。
再写一个Mutex类吧,在消息队列中,互斥区可是必须的,嘿嘿,当然这只是个示例,所以很简单:
//mutex.h #ifndef MUTEX_H #define MUTEX_H #include <pthread.h> class Mutex { public: Mutex() { pthread_mutex_init(&m_mutex, NULL); } ~Mutex() { pthread_mutex_destroy(&m_mutex); } void lock() { pthread_mutex_lock(&m_mutex); } void unlock() { pthread_mutex_unlock(&m_mutex); } private: pthread_mutex_t m_mutex; }; class ScopedMutex { public: ScopedMutex() { m_mutex.lock(); } ~ScopedMutex() { m_mutex.unlock(); } private: Mutex m_mutex; }; #endif
这里有两个类(Mutex, ScopedMutex),Mutex类很简单,只有lock,unlock两个方法,很容易看懂吧,当然这个类不支持递归加锁,千万不要那么做!
ScopedMutex类类似于boost里面的scoped_ptr,C++里面的auto_ptr,属于自动释放锁,或许叫smart lock更合适,在构造函数的时候上锁,析构的时候解锁,这样就可以不用再释放了,很方便,减少出错。
好了,暂时写到这里吧,下次写消息队列吧,这些都要用到就先写写了。
郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。