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_lock
和pthread_cond_wait
(假设您使用的是 POSIX 线程)。
【讨论】:
以上是关于While(1) 循环在不休眠的情况下减少 CPU的主要内容,如果未能解决你的问题,请参考以下文章
如何在不等待 1 秒的情况下对进程的 CPU 使用情况进行采样
如何在不使用 Timer 而是使用 Threads 的情况下实现平滑下降的 JLabel