如何处理过快的网络循环

How to deal with networking loops that are too fast?

本文关键字:网络 循环 何处理 处理      更新时间:2023-10-16

我有一个程序,其连接处理线程具有循环。问题是循环运行太快并消耗 100% CPU 内核。

如果没有客户端,我尝试在末尾放置一个std::this_thread::sleep_for(std::chrono::milliseconds(1));(或类似)(显然,当有客户端时问题仍然存在),它确实解决了 CPU 占用问题,但它也会延迟响应新连接。睡眠不可靠,不能太小,通常会导致> 1 毫秒。如果睡眠时间很短,它无论如何都不会真正导致高效的睡眠(1-3% 的 CPU 内核消耗)。

处理它的好方法是什么?

主动等待很少是一个好主意。 通常,将等待委托给系统并在事件发生时被唤醒是一种更好的方法。

在 Linux 系统上,poll() 正是这样做的:

#include <poll.h>
// ...
::poll(&fds, nfds, timeout);

等待(块)timeout毫秒,以便在 fds 的任何文件描述符上发生事件。


作为与文件描述符无关的情况的替代方案,我会使用 pthread_cond_wait()pthread_cond_signal() 。这些使用互斥锁和条件:

  • pthread_cond_wait(&cond, &mutex)解锁mutex并立即使线程进入睡眠状态,直到满足cond(发出信号),但随后它会重新获取互斥锁。

  • pthread_cond_signal(&cond) 向所有等待的线程发出信号,cond条件可能已更改。

典型的用法是:

worker thread:
    ::pthread_mutex_lock(&mutex);
    while (condition == false) {
        ::pthread_cond_wait(&cond, &mutex); // passive wait
    }
    // this part is only invoked when:
    // - condition is true
    // - mutex has been acquired
    ::pthread_mutex_unlock(&mutex);
thread handling connection/deconnection:
    ::pthread_mutex_lock(&mutex);
    // add/remove clients
    ::pthread_cond_signal(&cond);
    ::pthread_mutex_unlock(&mutex);

看:

  • pthread_cond_wait()

  • pthread_cond_signal()

  • pthread_cond_init()/pthread_cond_destroy()