CPU 100% 使用 ZeroMQ 发布者 (C)
CPU usage at 100% with ZeroMQ publisher (C)
我正在用 C 语言编写一个 ZeroMQ Publisher,它在 while 循环中发送一条消息。我将其高水位线设置为“20”:
int sndhwm = 20;
size_t sndhwm_size = sizeof(sndhwm);
int rc = zmq_setsockopt(publisher, ZMQ_SNDHWM, &sndhwm, sndhwm_size);
这段代码是我在bind
之前写的。绑定后,我打印水印的值,以确保它已设置:
int sndhwm2;
size_t sndhwm_size2 = sizeof(sndhwm2);
rc = zmq_getsockopt(publisher, ZMQ_SNDHWM, &sndhwm2, &sndhwm_size2);
printf("sndhwm: %i\n",sndhwm2);
它正确地打印了结果。
然而,当我运行程序时,CPU使用率几乎总是在100%。
我注意到如果在每次 send
之后执行 sleep(1)
,然后 CPU 使用率非常接近 0%,则不会发生这种情况。
这可能是什么问题?为什么 CPU 核心是 100%?跟设置水印有关系吗?
编辑: 我正在使用 libzmq3-dev 版本 4.2.5。
edit2: 抱歉,出于某种原因,我将内存泄漏误认为是 CPU 核心使用。我相应地编辑了问题。
这是可重现的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "zhelpers.h"
int main(int argc, char *argv []){
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
char buffer[50];
snprintf(buffer, sizeof(buffer), "tcp://127.0.0.1:5000");
int sndhwm = 20;
size_t sndhwm_size = sizeof(sndhwm);
int rc = zmq_setsockopt(publisher, ZMQ_SNDHWM, &sndhwm, sndhwm_size);
rc = zmq_bind(publisher, buffer);
int sndhwm2;
size_t sndhwm_size2 = sizeof(sndhwm2);
rc = zmq_getsockopt(publisher, ZMQ_SNDHWM, &sndhwm2, &sndhwm_size2);
assert(rc == 0);
while (1){
rc = s_send(publisher, "hello");
//sleep(1);
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
像这样的紧密循环通常会达到 100% CPU。为什么你认为不应该?
如果您添加 sleep()
,您的进程将在每次迭代时休眠 1 秒。对于 CPU 来说,这是一个很长的时间,如果没有其他密集进程 运行,CPU 使用率通常会变为 0%。运行。
当发布者套接字达到高水位线时,我认为它只会丢弃任何新消息。这基本上是一个 no-op(没有操作),它给出了一个紧密的循环,这导致 100% CPU 使用率。
如果在 未设置 高水位线时未看到 100% CPU 使用率,我认为发布者会继续缓冲新消息,尤其是如果没有订阅者连接。这涉及到内存分配,这是一个比较慢的操作。这可能会降低 CPU 的使用率,因为 CPU 必须等待内存、交换到磁盘等。
要控制行为,您可以让 pub 套接字在发送操作因缓冲区已满而失败时通知您。这样你就可以决定什么时候让你的循环休眠。
你需要。
- 在
zmq_send
上传递标志 ZMQ_DONTWAIT
- 检查
zmq_send
return 失败值 (-1)
- 如果失败,请检查 errno(以确定是命中 HWM 还是真正的错误)
顺便说一句,我不确定 s_send
将 return 是什么,但最好使用 libzmq 或 cppzmq 中提供的函数。
我正在用 C 语言编写一个 ZeroMQ Publisher,它在 while 循环中发送一条消息。我将其高水位线设置为“20”:
int sndhwm = 20;
size_t sndhwm_size = sizeof(sndhwm);
int rc = zmq_setsockopt(publisher, ZMQ_SNDHWM, &sndhwm, sndhwm_size);
这段代码是我在bind
之前写的。绑定后,我打印水印的值,以确保它已设置:
int sndhwm2;
size_t sndhwm_size2 = sizeof(sndhwm2);
rc = zmq_getsockopt(publisher, ZMQ_SNDHWM, &sndhwm2, &sndhwm_size2);
printf("sndhwm: %i\n",sndhwm2);
它正确地打印了结果。
然而,当我运行程序时,CPU使用率几乎总是在100%。
我注意到如果在每次 send
之后执行 sleep(1)
,然后 CPU 使用率非常接近 0%,则不会发生这种情况。
这可能是什么问题?为什么 CPU 核心是 100%?跟设置水印有关系吗?
编辑: 我正在使用 libzmq3-dev 版本 4.2.5。
edit2: 抱歉,出于某种原因,我将内存泄漏误认为是 CPU 核心使用。我相应地编辑了问题。
这是可重现的例子:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include "zhelpers.h"
int main(int argc, char *argv []){
void *context = zmq_ctx_new();
void *publisher = zmq_socket(context, ZMQ_PUB);
char buffer[50];
snprintf(buffer, sizeof(buffer), "tcp://127.0.0.1:5000");
int sndhwm = 20;
size_t sndhwm_size = sizeof(sndhwm);
int rc = zmq_setsockopt(publisher, ZMQ_SNDHWM, &sndhwm, sndhwm_size);
rc = zmq_bind(publisher, buffer);
int sndhwm2;
size_t sndhwm_size2 = sizeof(sndhwm2);
rc = zmq_getsockopt(publisher, ZMQ_SNDHWM, &sndhwm2, &sndhwm_size2);
assert(rc == 0);
while (1){
rc = s_send(publisher, "hello");
//sleep(1);
}
zmq_close(publisher);
zmq_ctx_destroy(context);
return 0;
}
像这样的紧密循环通常会达到 100% CPU。为什么你认为不应该?
如果您添加 sleep()
,您的进程将在每次迭代时休眠 1 秒。对于 CPU 来说,这是一个很长的时间,如果没有其他密集进程 运行,CPU 使用率通常会变为 0%。运行。
当发布者套接字达到高水位线时,我认为它只会丢弃任何新消息。这基本上是一个 no-op(没有操作),它给出了一个紧密的循环,这导致 100% CPU 使用率。
如果在 未设置 高水位线时未看到 100% CPU 使用率,我认为发布者会继续缓冲新消息,尤其是如果没有订阅者连接。这涉及到内存分配,这是一个比较慢的操作。这可能会降低 CPU 的使用率,因为 CPU 必须等待内存、交换到磁盘等。
要控制行为,您可以让 pub 套接字在发送操作因缓冲区已满而失败时通知您。这样你就可以决定什么时候让你的循环休眠。
你需要。
- 在
zmq_send
上传递标志 - 检查
zmq_send
return 失败值 (-1) - 如果失败,请检查 errno(以确定是命中 HWM 还是真正的错误)
ZMQ_DONTWAIT
顺便说一句,我不确定 s_send
将 return 是什么,但最好使用 libzmq 或 cppzmq 中提供的函数。