【问题标题】:CPU usage at 100% with ZeroMQ publisher (C)ZeroMQ 发布者 (C) 的 CPU 使用率为 100%
【发布时间】:2020-02-21 21:07:35
【问题描述】:

我正在用 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;
}

【问题讨论】:

  • 也许您也应该在调用 send 的地方发布代码,以及在那里使用/分配的任何相关数据结构(基本上是 minimal reproducible example)。

标签: c cpu zeromq


【解决方案1】:

要控制行为,您可以告诉 pub 套接字,如果发送操作因缓冲区已满而失败,则通知您。这样你就可以决定什么时候让你的循环休眠。

你需要。

  • zmq_send 上传递标志ZMQ_DONTWAIT
  • 检查zmq_send返回值是否失败(-1)
  • 如果失败,请检查 errno(以确定命中 HWM 和真正的错误之间)

顺便说一句,我不确定s_send 会返回什么,但最好使用 libzmq 或 cppzmq 中提供的函数。

【讨论】:

    【解决方案2】:

    这样的紧密循环通常会导致 100% 的 CPU。为什么你认为它不应该?

    如果您添加sleep(),您的进程将在每次迭代中休眠 1 秒。这对于 CPU 来说是一个很长的时间,如果没有其他密集型进程正在运行,CPU 使用率通常会降到 0%。

    当发布者套接字达到高水位标记时,我认为它只会丢弃任何新消息。这基本上是一个无操作(无操作),它提供了一个紧密的循环,这会导致 100% 的 CPU 使用率。

    如果您在不设置高水位标记时没有看到 100% 的 CPU 使用率,我认为发布者将继续缓冲新消息,尤其是在没有连接订阅者的情况下。这涉及到内存分配,这是一个相对较慢的操作。这可能会降低 CPU 使用率,因为 CPU 必须等待内存、交换到磁盘等。

    【讨论】:

    • 我敢打赌,即使有无限大的 ZMQ_SNDHWM,您也会看到 100% 的 CPU 核心利用率,因为循环仍然会保持非常快(直到交换开始)跨度>
    猜你喜欢
    • 1970-01-01
    • 2017-08-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多