В большинстве операционных систем есть системный вызов для эффективного ожидания событий на объектах. На Linux этот системный вызов - poll()
, а объекты являются дескрипторами файлов.
Поскольку сокеты ZeroMQ не являются дескрипторами файлов, вы не можете использовать poll()
с сокетами ZeroMQ. Поэтому стоит zmq_poll()
. В качестве дополнительного бонуса zmq_poll()
позволяет вам ждать событий в файловых дескрипторах сокетов ZeroMQ и . Это полезно для многих программ. Например, если у вас есть интерактивная программа, вы хотите дождаться событий на сокетах ZeroMQ и ввод с клавиатуры со стандартного ввода, который является дескриптором файла.
Относительно вашего кода и ваших вопросов :
zmq_poll()
имеет аргумент тайм-аута. Нет необходимости создавать таймер самостоятельно. - Вы должны установить только
.socket
или член .fd
из zmq_pollitem_t
, но не оба сразу. Установите другое значение 0. Если вы установите оба параметра, ZeroMQ будет игнорировать элемент .fd
. - Когда вы вызываете
zmq_poll()
, ваша программа будет блокироваться до тех пор, пока не вернется zmq_poll()
. zmq_poll()
возвращает либо, когда событие происходит на одном из zmq_pollitem_t
s , либо , когда истекает время ожидания. - Вы можете подождать столько
zmq_pollitem_t
s, сколько вам нужно. Это зависит от вашей программы. Например, сервер может обрабатывать несколько подключений, и вы создаете zmq_pollitem_t
для каждого подключения.
Следующий пример кода ожидает сокета ZeroMQ и дескриптора файла.
void wait_for_socket_and_fd(void* sock, int fd, long timeout)
{
// wait for two objects
zmq_pollitem_t items[2];
// wait for ZeroMQ socket...
items[0].socket = sock;
items[0].fd = 0;
items[0].events = ZMQ_POLLIN;
// ...and wait for fd
items[1].socket = NULL;
items[1].fd = fd;
items[1].events = ZMQ_POLLIN;
// block until event occurs or timeout expires
int ret = zmq_poll(items, sizeof(items) / sizeof(items[0]), timeout);
if (ret > 0)
{
// event occurred
if (items[0].revents != 0)
{
// event occurred on sock, process it
}
if (items[1].revents != 0)
{
// event occurred on fd, process it
}
}
else if (ret == 0)
{
// timeout expired, do something
}
else
{
// error occurred, handle it
}
}