经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » C 语言 » 查看文章
Muduo学习笔记(一) 什么都不做的EventLoop
来源:cnblogs  作者:艾露米婭娜  时间:2018/10/26 9:52:09  对本文有异议

Muduo学习笔记(一) 什么都不做的EventLoop

EventLoop

EventLoop的基本接口包括构造、析构、loop()。
One Loop Per Thread 一个线程只有一个EventLoop对象、如果当前线程创建了其他 EventLoop对象,则终止程序.

CurrentThread

CurrentThread 通过__thread 关键字和系统调用syscall() 保存获取线程的的pid(不通于线程tid,tid属于进程,进程内唯一,线程pid属于内核).

  1. #ifndef _CURRENT_THREAD
  2. #define _CURRENT_THREAD
  3.  
  4. #include <stdint.h>
  5. #include <stdio.h>
  6. #include <sys/syscall.h>
  7. #include <pthread.h>
  8. #include <unistd.h>
  9.  
  10. namespace CurrentThread
  11. {
  12.   // internal
  13.   extern __thread int t_cachedTid;
  14.   extern __thread char t_tidString[32];
  15.   extern __thread int t_tidStringLength;
  16.   extern __thread const char* t_threadName;
  17.  
  18.   inline int tid()
  19.   {
  20.     if (__builtin_expect(t_cachedTid == 0, 0))
  21.     {
  22.       if (t_cachedTid == 0)
  23.       {
  24.         t_cachedTid = static_cast<pid_t>(::syscall(SYS_gettid));
  25.         t_tidStringLength = snprintf(t_tidString, sizeof t_tidString, "%5d ", t_cachedTid);
  26.       }
  27.     }
  28.     return t_cachedTid;
  29.   }
  30.  
  31.   inline const char* tidString() // for logging
  32.   {
  33.     return t_tidString;
  34.   }
  35.  
  36.   inline int tidStringLength() // for logging
  37.   {
  38.     return t_tidStringLength;
  39.   }
  40.  
  41.   inline const char* name()
  42.   {
  43.     return t_threadName;
  44.   }
  45. }
  46.  
  47. #endif
  48.  
  49. //CurrentThread.cpp
  50.  
  51. #include "CurrentThread.hh"
  52.  
  53. namespace CurrentThread
  54. {
  55.  
  56.   __thread int t_cachedTid = 0;
  57.   __thread char t_tidString[32];
  58.   __thread int t_tidStringLength = 6;
  59.   __thread const char* t_threadName = "unknown";
  60.  
  61. }

getEventLoopOfCurrentThread

每个线程至多有一个EventLoop对象,那么我们通过static 成员函数getEventLoopOfCurrentThread() 返回此对象.

  1. EventLoop* EventLoop::getEventLoopOfCurrentThread()
  2. {
  3.   return t_loopInThisThread;
  4. }

EventLoop 源代码

  1. #ifndef NET_EVENTLOOP_H
  2. #define NET_EVENTLOOP_H
  3.  
  4. #include "CurrentThread.hh"
  5.  
  6. class EventLoop
  7. {
  8. public:
  9.     EventLoop();
  10.     ~EventLoop();
  11.     void loop();
  12.  
  13.     void assertInLoopThread()
  14.     {
  15.         if(!isInloopThread())
  16.         {
  17.             abortNotInLoopThread();
  18.         }
  19.     }
  20.  
  21.     bool isInloopThread() const {return m_threadId == CurrentThread::tid(); }
  22.  
  23.  
  24.     static EventLoop* getEventLoopOfCurrentThread();
  25.  
  26. private:
  27.     EventLoop& operator=(const EventLoop&);
  28.     EventLoop(const EventLoop&);
  29.  
  30.     void abortNotInLoopThread();
  31.     bool m_looping;
  32.     const pid_t m_threadId;
  33. };
  34.  
  35. #endif
  36.  
  37. // EventLoop.cpp
  38.  
  39. #include "EventLoop.hh"
  40. #include "Logger.hh"
  41. #include <assert.h>
  42. #include <poll.h>
  43.  
  44. __thread EventLoop* t_loopInThisThread = 0;
  45.  
  46. EventLoop::EventLoop()
  47.     :m_looping(false),
  48.   m_threadId(CurrentThread::tid())
  49. {
  50.   LOG_TRACE << "EventLoop Create " << this << " in thread " << m_threadId;
  51.   if(t_loopInThisThread)
  52.   {  //每个线程只有一个EventLoop对象 , 如果当前线程创建了其他 EventLoop对象,则终止程序.
  53.     LOG_FATAL << "Anthor EventLoop " << t_loopInThisThread
  54.               << " exists in this thread " << m_threadId;
  55.   }
  56.   else
  57.   {
  58.     t_loopInThisThread = this;
  59.   }
  60. }
  61.  
  62. EventLoop::~EventLoop()
  63. {
  64.   assert(!m_looping);
  65.   t_loopInThisThread = NULL;
  66. }
  67.  
  68. void EventLoop::loop()
  69. {
  70.   assert(!m_looping);
  71.   assertInLoopThread();
  72.   m_looping = true;
  73.  
  74.   LOG_TRACE << "EventLoop " << this << " start loopig";
  75.  
  76.   ::poll(NULL, 0, 3*1000);
  77.  
  78.   LOG_TRACE << "EventLoop " << this << " stop loopig";
  79.   m_looping = false;
  80.  
  81. }
  82.  
  83. void EventLoop::abortNotInLoopThread()
  84. {
  85.   LOG_FATAL << "EventLoop::abortNotInLoopThread - EventLoop " << this
  86.             << " was created in threadId_ = " << m_threadId
  87.             << ", current thread id = " <<  CurrentThread::tid();
  88. }
  89.  
  90. EventLoop* EventLoop::getEventLoopOfCurrentThread()
  91. {
  92.   return t_loopInThisThread;
  93. }

测试程序

test1

正确的逻辑.

  1. #include <errno.h>
  2. #include "EventLoop.hh"
  3. #include <thread>
  4.  
  5. int main()
  6. {
  7.   EventLoop testloop;
  8.  
  9.   testloop.loop();
  10.  
  11.   return 0;
  12. }
  1. ./test.out 
  2. 2018-10-25 20:01:03.287601 [TRACE] [EventLoop.cpp:12] [EventLoop] EventLoop Create 0x7FFF7B1E2780 in thread 2086
  3. 2018-10-25 20:01:03.287750 [TRACE] [EventLoop.cpp:36] [loop] EventLoop 0x7FFF7B1E2780 start loopig
  4. 2018-10-25 20:01:06.291622 [TRACE] [EventLoop.cpp:40] [loop] EventLoop 0x7FFF7B1E2780 stop loopig

test2

企图在当前线程启用其他线程创建的EventLoop对象

  1. #include <errno.h>
  2. #include "EventLoop.hh"
  3. #include <thread>
  4.  
  5. EventLoop* g_loop;
  6.  
  7. void test()
  8. {
  9.  
  10.   g_loop->loop();
  11.  
  12. }
  13.  
  14. int main()
  15. {
  16.   EventLoop testloop;
  17.  
  18.   //testloop.loop();
  19.  
  20.   g_loop = &testloop;
  21.  
  22.   std::thread test_thread(test);
  23.  
  24.   test_thread.join();
  25.  
  26.   return 0;
  27. }
  1. ./test.out 
  2. 2018-10-25 20:05:49.618701 [TRACE] [EventLoop.cpp:12] [EventLoop] EventLoop Create 0x7FFCA55A35F0 in thread 2114
  3. 2018-10-25 20:05:49.619057 [FATAL] [EventLoop.cpp:47] EventLoop::abortNotInLoopThread - EventLoop 0x7FFCA55A35F0 was created in threadId_ = 2114, current thread id = 2115
  4. Aborted (core dumped)

懒癌晚期,说明简短,不过这个看代码都好懂我也没必要写太多,对吧。

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号