EventLoopThread

EventLoopThread

1 类图
  • 任何一个线程只要创建并运行了EventLoop都是IO线程
  • IO线程不一定是主线程(IO,逻辑运算)
  • EventLoopThread创建了一个线程
  • 在线程函数中创建一个EventLoop::loop开启事件轮询
#include <EventLoopThread.h>

继承自 noncopyable .

[图例]

Public 类型
typedef boost::function< void(EventLoop *)>ThreadInitCallback
Public 成员函数
EventLoopThread (const ThreadInitCallback &cb=ThreadInitCallback())
~EventLoopThread ()
EventLoop *startLoop () 启动线程,调用thread.start()函数,令他成为IO线程,把指针指向创建EventLoop
Private 成员函数
voidthreadFunc () 线程函数
Private 属性
EventLoop *loop_ loop_指针指向一个EventLoop对象
boolexiting_
Threadthread_
MutexLockmutex_
Conditioncond_
ThreadInitCallbackcallback_ 线程初始化的回调函数,在事件循环之前被调用
2 构造函数
EventLoopThread::EventLoopThread(const ThreadInitCallback &cb)
	: loop_(NULL),
	  exiting_(false),
	  thread_(boost::bind(&EventLoopThread::threadFunc, this)),
	  mutex_(),
	  cond_(mutex_),
	  callback_(cb)
{
}
// threadFunc 绑定一个线程处理函数 当启动线程时,会创建一个loop对象
void EventLoopThread::threadFunc()
{
	EventLoop loop;
	if (callback_) // 如果注册了回调函数
	{
		callback_(&loop); // 执行回调函数
	}
	{
		MutexLockGuard lock(mutex_);
		loop_ = &loop;
		cond_.notify();
	}
	loop.loop(); // 开启事件轮询
    // 如果结束了事件轮询,就会退出这个线程,所以loop_指向了栈对象也没关系
}
3 析构函数
EventLoopThread::~EventLoopThread()
{
	exiting_ = true;
	loop_->quit();
	thread_.join(); // pthread_join回收线程
}
void EventLoop::quit()
{
	quit_ = true;
	if (!isInLoopThread()) // 如果是io线程 eventfd唤醒通知其他线程
	{
		wakeup();
	}
}
4 启动线程
EventLoop *EventLoopThread::startLoop()
{
	assert(!thread_.started()); // 断言该线程没有被启动
	thread_.start();			// 启动线程,回调之前的threadFunc 会开启loop轮询

	{
		MutexLockGuard lock(mutex_);
		while (loop_ == NULL)
		{
			cond_.wait(); // 条件变量的等待,必须要等启动的io子线程通知父线程已经初始化完毕
		}
	}
	return loop_;
}
5 测试用例
#include <muduo/net/EventLoop.h>
#include <muduo/net/EventLoopThread.h>
#include <iostream>
#include <stdio.h>

using namespace muduo;
using namespace muduo::net;

void runInThread()
{
	printf("runInThread(): pid = %d, tid = %d ---------------------------启动io线程\n",
		   getpid(), CurrentThread::tid());
}

void startEventLoop()
{
	printf("start EventLoop ==============================启动\n");
}
void runThread(int a)
{
	printf("aaaaaaaaaa =========== %d\n",a);
}
int main()
{
	printf("main(): pid = %d, tid = %d\n",
		   getpid(), CurrentThread::tid());
	auto f1 = std::bind(startEventLoop);
	EventLoopThread loopThread(f1);
	EventLoop *loop = loopThread.startLoop();
	// 异步调用runInThread,即将runInThread添加到loop对象所在IO线程,让该IO线程执行
	loop->runInLoop(runInThread);
	sleep(1);
	// runAfter内部也调用了runInLoop,所以这里也是异步调用
	loop->runAfter(1,std::bind(runThread,1));
	loop->runAfter(2, runInThread);
    loop->runAfter(1,std::bind(runThread,1));

    // 连续添加3个定时器,会刷新第一次,和第三次的定时器得最早到期时间
	sleep(3);
	loop->quit();

	printf("exit main().\n");
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值