While(1) 循环在不休眠的情况下减少 CPU

Posted

技术标签:

【中文标题】While(1) 循环在不休眠的情况下减少 CPU【英文标题】:While(1) loop reduce cpu without sleep 【发布时间】:2014-11-25 17:13:29 【问题描述】:

我的问题是我正在使用 rawsocket 传递高速率(大于 50kpps)流量,两个线程,一个是发送(从缓冲区读取),另一个是接收(写入缓冲区)。

我必须使用 while(1) 循环来确保无限循环,并且我不能使用 usleep 从那时起我将丢失数据包(我已经尝试过)......现在 cpu 使用率为 100%,我想我我正在烧我的cpu...

代码如下:

while (1)


  if (sendIndex == PACKET_COUNT_MAX)

  sendIndex = 0;

  else if (ringBuffer[sendIndex].drop == 0)
if(sendtosocket (ringBuffer, sendIndex, rawout) < 0)
    a++;
    else
    sendIndex++;
  else if (ringBuffer[sendIndex].drop == 1) 
            ringBuffer[sendIndex].header.free = 1;
            memset (ringBuffer[sendIndex].data, 0, sizeof (ringBuffer[sendIndex].data));
            sendIndex++;
           
  else

  a++;

    //nanosleep((struct timespec[])0, 5, NULL);

提前谢谢!!!!!!! 丽莎

【问题讨论】:

发送线程在没有要发送的情况下怎么办?是什么保护ringBuffer 不被并发访问破坏? 如果只有一个生产者和一个消费者,那么无锁环形缓冲区相当容易。 我更担心其他效率低下。没有 condvar 或 semaphore:CPU 轮询循环。有趣的 memset 东西归零缓冲空间,不知道为什么。 【参考方案1】:

您需要将控制权交给内核。您可能会发现有用的命令是select。在http://manpages.courier-mta.org/htmlman2/select.2.html 上查看整个故事。欲了解更多信息,http://www.gnu.org/software/libc/manual/html_node/Waiting-for-I_002fO.html。

这一切都是为了知道你除了等待来自网络的输入之外别无他法。或者文件系统。或其他任何文件描述符(U*ix 术语)。所以,一旦你有东西要处理,你就让内核唤醒你。

【讨论】:

【参考方案2】:

你可以试试

    增加接收缓冲区 通过睡眠减慢 sendto,不应该丢失数据包 将 MSG_WAITALL 标志与 recvfrom 一起使用以使其成为阻塞读取,并确保未使用 SOCK_NONBLOCK 或 O_NONBLOCK 打开套接字

【讨论】:

【参考方案3】:

您需要在线程之间进行合理的同步。这包括:

    使用某种锁来确保变量不会被一个线程读取,而它正在或可能被另一个线程修改。

    使用某种等待方案,以便发送线程可以等待有工作,而无需旋转。

查看pthread_mutex_lockpthread_cond_wait(假设您使用的是 POSIX 线程)。

【讨论】:

以上是关于While(1) 循环在不休眠的情况下减少 CPU的主要内容,如果未能解决你的问题,请参考以下文章

如何在不等待 1 秒的情况下对进程的 CPU 使用情况进行采样

在不使用while循环的情况下找到最内部的异常?

如何在不使用 Timer 而是使用 Threads 的情况下实现平滑下降的 JLabel

如何在不使用while循环的情况下获取xml内容

在不调用属性的情况下获取休眠惰性关系 n+1 - Kotlin

在不休眠的情况下使用 VBScript 压缩文件