qinguoyi / TinyWebServer

:fire: Linux下C++轻量级WebServer服务器
Apache License 2.0
16.94k stars 3.97k forks source link

接#70:reactor模式的效率比模拟preactor模式的效率低吗 #137

Closed tomatowithpotato closed 2 years ago

tomatowithpotato commented 2 years ago

这个问题是来源于#70,元问题描述为:

在reator模式中,IO读写是多线程并行的, 但是模拟preactor模式中,IO读写都是在主线程中串行完成的, 按道理说,并行reactor会更快才对。

但是从参考的运行结果看,reactor并没有明显的性能优势,这是为什么呢? 是收到了测试环境的影响吗? 还是IO读写在整个过程中占比很小,并不是耗时的大头?

后来我看大家的评论,发现reator慢的原因是因为 “代码中将读事件插入阻塞队列中后有一个while(true)循环一直等到线程从阻塞队列中取此http链接后接受数据后才break。相当于阻塞队列中永远至多有一个http连接” by @lxl999

//若监测到读事件,将该事件放入请求队列
m_pool->append(users + sockfd, 0);

while (true)
{
    if (1 == users[sockfd].improv)
    {
        if (1 == users[sockfd].timer_flag)
        {
            deal_timer(timer, sockfd);
            users[sockfd].timer_flag = 0;
        }
        users[sockfd].improv = 0;
        break;
    }
}

所以为什么把事件插入队列后,要加这个循环等待连接被处理才break呢?是为了处理timer?还是为什么呢? 这样做的话就不是并发,而是串行了,不知有无大佬知道怎么解决这个问题

HandsomeJims commented 2 years ago

从代码上看,这里是为了当http读写失败后,直接将其对应的链接从定时器中删除;但是疑惑的是,定时器本来就会在超时之后自动删除的,这里为何要多次一举呢?暂时还没想明白

tomatowithpotato commented 2 years ago

70已有人给出一个答案,可移步#70