EventLoopThread

EventLoopThread,第1张

EventLoopThread EventLoopThread 1 类图

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

#include 

继承自 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 
#include 
#include 
#include 

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 =========== %dn",a);
}
int main()
{
	printf("main(): pid = %d, tid = %dn",
		   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");
}

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5714047.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-17
下一篇 2022-12-17

发表评论

登录后才能评论

评论列表(0条)

保存