qinguoyi / TinyWebServer

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

线程池 threadpool<T>::run() 函数中,为什么要判断 request 非NULL? #276

Open arglone opened 1 month ago

arglone commented 1 month ago

我想不到任何一种情况会导致 requestNULL,也就是下面的代码我觉得是没必要的:

    if (!request)
        continue;

threadpool<T>::run() 用的 request 最先是 WebServer::dealwithwrite()WebServer::dealwithread()append 操作进来的。append 是类似 m_pool->append(users + sockfd, 1); 这样直接操作的 users 数组。但是我们看到 WebServer::WebServer() 构造函数内是直接 users = new http_conn[MAX_FD]; 的,因此 users + sockfd 在任何时候都不可能为NULL。即使 WebServer::~WebServer() 析构函数内做了 delete[] users;,但 delete 关键字本身也不会改变指针的值,所以根本想不到为什么代码中要判断 requestNULL....

看看有无大佬分析一下这里。

arglone commented 1 month ago

我又发现threadpool<T>::run()还有一部分也有问题,明明已经wait到了semaphore,还要再判断一次队列非空:

        m_queuestat.wait();
        m_queuelocker.lock();
        if (m_workqueue.empty())
        {
            m_queuelocker.unlock();
            continue;
        }

我也想不到任何触发这个if的情况。我查了下,sem_post() 是只会唤醒一个线程的。而且,如果想要 lock(),必须要先 wait(),所以也不存在 wait() 醒来后 lock() 没抢过的情况。总之,就是怎么也不会存在虚假唤醒的情况。

我只能理解这里是在做防御性编程了。。 但是把,如果是防御性编程,connection_pool::GetConnection() 中也是有几乎一样的代码,不过,此时却又没有这样再次判断了。真的让人迷惑。