Muduo学习笔记(一) 什么都不做的EventLoop
EventLoop
EventLoop的基本接口包括构造、析构、loop()。
One Loop Per Thread 一个线程只有一个EventLoop对象、如果当前线程创建了其他 EventLoop对象,则终止程序.
CurrentThread
CurrentThread 通过__thread 关键字和系统调用syscall() 保存获取线程的的pid(不通于线程tid,tid属于进程,进程内唯一,线程pid属于内核).
- #ifndef _CURRENT_THREAD
- #define _CURRENT_THREAD
-
- #include <stdint.h>
- #include <stdio.h>
- #include <sys/syscall.h>
- #include <pthread.h>
- #include <unistd.h>
-
- namespace CurrentThread
- {
- // internal
- extern __thread int t_cachedTid;
- extern __thread char t_tidString[32];
- extern __thread int t_tidStringLength;
- extern __thread const char* t_threadName;
-
- inline int tid()
- {
- if (__builtin_expect(t_cachedTid == 0, 0))
- {
- if (t_cachedTid == 0)
- {
- t_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid));
- t_tidStringLength = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);
- }
- }
- return t_cachedTid;
- }
-
- inline const char* tidString() // for logging
- {
- return t_tidString;
- }
-
- inline int tidStringLength() // for logging
- {
- return t_tidStringLength;
- }
-
- inline const char* name()
- {
- return t_threadName;
- }
- }
-
- #endif
-
- //CurrentThread.cpp
-
- #include "CurrentThread.hh"
-
- namespace CurrentThread
- {
-
- __thread int t_cachedTid = 0;
- __thread char t_tidString[32];
- __thread int t_tidStringLength = 6;
- __thread const char* t_threadName = "unknown";
-
- }
getEventLoopOfCurrentThread
每个线程至多有一个EventLoop对象,那么我们通过static 成员函数getEventLoopOfCurrentThread() 返回此对象.
- EventLoop* EventLoop::getEventLoopOfCurrentThread()
- {
- return t_loopInThisThread;
- }
EventLoop 源代码
- #ifndef NET_EVENTLOOP_H
- #define NET_EVENTLOOP_H
-
- #include "CurrentThread.hh"
-
- class EventLoop
- {
- public:
- EventLoop();
- ~EventLoop();
- void loop();
-
- void assertInLoopThread()
- {
- if(!isInloopThread())
- {
- abortNotInLoopThread();
- }
- }
-
- bool isInloopThread() const {return m_threadId == CurrentThread::tid(); }
-
-
- static EventLoop* getEventLoopOfCurrentThread();
-
- private:
- EventLoop& operator=(const EventLoop&);
- EventLoop(const EventLoop&);
-
- void abortNotInLoopThread();
- bool m_looping;
- const pid_t m_threadId;
- };
-
- #endif
-
- // EventLoop.cpp
-
- #include "EventLoop.hh"
- #include "Logger.hh"
- #include <assert.h>
- #include <poll.h>
-
- __thread EventLoop* t_loopInThisThread = 0;
-
- EventLoop::EventLoop()
- :m_looping(false),
- m_threadId(CurrentThread::tid())
- {
- LOG_TRACE << "EventLoop Create " << this << " in thread " << m_threadId;
- if(t_loopInThisThread)
- { //每个线程只有一个EventLoop对象 , 如果当前线程创建了其他 EventLoop对象,则终止程序.
- LOG_FATAL << "Anthor EventLoop " << t_loopInThisThread
- << " exists in this thread " << m_threadId;
- }
- else
- {
- t_loopInThisThread = this;
- }
- }
-
- EventLoop::~EventLoop()
- {
- assert(!m_looping);
- t_loopInThisThread = NULL;
- }
-
- void EventLoop::loop()
- {
- assert(!m_looping);
- assertInLoopThread();
- m_looping = true;
-
- LOG_TRACE << "EventLoop " << this << " start loopig";
-
- ::poll(NULL, 0, 3*1000);
-
- LOG_TRACE << "EventLoop " << this << " stop loopig";
- m_looping = false;
-
- }
-
- void EventLoop::abortNotInLoopThread()
- {
- LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this
- << " was created in threadId_ = " << m_threadId
- << ", current thread id = " << CurrentThread::tid();
- }
-
- EventLoop* EventLoop::getEventLoopOfCurrentThread()
- {
- return t_loopInThisThread;
- }
测试程序
test1
正确的逻辑.
- #include <errno.h>
- #include "EventLoop.hh"
- #include <thread>
-
- int main()
- {
- EventLoop testloop;
-
- testloop.loop();
-
- return 0;
- }
- ./test.out
- 2018-10-25 20:01:03.287601 [TRACE] [EventLoop.cpp:12] [EventLoop] EventLoop Create 0x7FFF7B1E2780 in thread 2086
- 2018-10-25 20:01:03.287750 [TRACE] [EventLoop.cpp:36] [loop] EventLoop 0x7FFF7B1E2780 start loopig
- 2018-10-25 20:01:06.291622 [TRACE] [EventLoop.cpp:40] [loop] EventLoop 0x7FFF7B1E2780 stop loopig
test2
企图在当前线程启用其他线程创建的EventLoop对象
- #include <errno.h>
- #include "EventLoop.hh"
- #include <thread>
-
- EventLoop* g_loop;
-
- void test()
- {
-
- g_loop->loop();
-
- }
-
- int main()
- {
- EventLoop testloop;
-
- //testloop.loop();
-
- g_loop = &testloop;
-
- std::thread test_thread(test);
-
- test_thread.join();
-
- return 0;
- }
- ./test.out
- 2018-10-25 20:05:49.618701 [TRACE] [EventLoop.cpp:12] [EventLoop] EventLoop Create 0x7FFCA55A35F0 in thread 2114
- 2018-10-25 20:05:49.619057 [FATAL] [EventLoop.cpp:47] EventLoop::abortNotInLoopThread - EventLoop 0x7FFCA55A35F0 was created in threadId_ = 2114, current thread id = 2115
- Aborted (core dumped)
懒癌晚期,说明简短,不过这个看代码都好懂我也没必要写太多,对吧。