Reputation: 341
I'm writing a ZeroMQ Publisher in C that sends a single message in a while loop. I set its high watermark as "20":
int sndhwm = 20;
size_t sndhwm_size = sizeof(sndhwm);
int rc = zmq_setsockopt(publisher, ZMQ_SNDHWM, &sndhwm, sndhwm_size);
I wrote this piece of code before the bind
. After the bind, I print the value of the watermark, just to make sure it was set:
int sndhwm2;
size_t sndhwm_size2 = sizeof(sndhwm2);
rc = zmq_getsockopt(publisher, ZMQ_SNDHWM, &sndhwm2, &sndhwm_size2);
printf("sndhwm: %i\n",sndhwm2);
It prints the result correctly.
However, when I run the program, CPU usage is almost always at 100%.
I noticed this does not happen if, after every send
, I execute a sleep(1)
, and then CPU usage is pretty close to 0%.
What could be the problem here? Why is the CPU core at 100%? Is it related to the set watermark?
edit: I'm using libzmq3-dev version 4.2.5.
edit2: My apologies, for some reason I mistook the memory leak with the CPU core usage. I edited the question accordingly.
This is the reproducible example:
#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;
}
Upvotes: 1
Views: 1140
Reputation: 1042
To control the behaviour you can tell the pub socket to inform you if the send operation failed due to a full buffer. That way you can decide when to sleep your loop.
You need to.
ZMQ_DONTWAIT
on zmq_send
zmq_send
return value for failure (-1) BTW I am not sure what s_send
will return is but it's probably best to use the functions provided in libzmq or cppzmq.
Upvotes: 1
Reputation: 4006
A tight loop like that will usually lead to 100% CPU. Why do you think it shouldn't?
If you add the sleep()
your process will go to sleep for 1 second on each iteration. This is a very long time for a CPU and CPU usage will usually go to 0%, if no other intensive processes are running.
When the publisher socket reaches the high water mark, I think it will just drop any new messages. This is basically a no-op (no operation), which gives a tight loop and this leads to 100% CPU usage.
If you do not see 100% CPU usage when you do not set the high water mark, I think the publisher will keep buffering new messages, especially if no subscribers are connected. This involves memory allocation, which is a relatively slow operation. This could give a lower a CPU usage as the CPU has to wait on memory, swapping to disk, etc..
Upvotes: 1