У меня есть два процесса, записанные в C, которые устанавливают PUSH/PULL
сокеты ZeroMQ и два потока в Python процессе, которые отражают сокеты PUSH/PULL
. Примерно 80–300 легких сообщений (<30 байт) в секунду отправляются из процесса C в процесс Python, и 10–30 аналогичных сообщений из процесса Python в процесс C. </p>
Я запускал эти сервисы на 64-битных ARMv8 (на основе Ubuntu) и AMD64 (Ubuntu 18.04) без заметных задержек. Я попытался запустить точно такие же сервисы в 32-битной системе Linux и был шокирован, увидев сообщения, приходящие более чем через 30 секунд, даже после уничтожения сервисов C. При проверке использования процессора, он был довольно плоским 30-40% и, похоже, не шейкой bottle.
Настройки моего сокета ZeroMQ не менялись между системами, я установил LINGER
на 0, я пробовал RCVTIMEO
между 0 и 100 мс, и я пытался варьировать BACKLOG
между 0 и 50, без разницы в любом случае. Я попытался использовать несколько потоков ввода-вывода и установить сходство потоков сокетов, также безрезультатно. Для сокетов PUSH
я подключаю разъемы на tcp://localhost:#####
и привязываю разъемы PULL
к tcp://*:#####
. Я также использовал ipc:///tmp/...
, сообщения отправлялись и принимались, но задержка все еще существовала в 32-битной системе.
Я исследовал другие Python шаги между приемом сообщений, и они не кажется, занимает не более миллисекунды. Когда я определяю время socket.recv(0)
, оно достигает 0,02 секунды, даже если для этого сокета установлено значение RCVTIMEO
.
Любые предположения, почему я вижу такое поведение на новой 32-битной платформе, а не на другие платформы? Возможно, я смотрю во всех неправильных местах?
Вот небольшой код, который поможет объяснить:
Соединение и метод класса _recv()
примерно изображены ниже:
def _connect(self):
self.context = zmq.Context(4)
self.sink = self.context.socket(zmq.PULL)
self.sink.setsockopt(zmq.LINGER, 0)
self.sink.setsockopt(zmq.RCVTIMEO, 100)
self.sink.setsockopt(zmq.BACKLOG, 0)
self.sink.bind("tcp://*:55755")
def _recv(self):
while True:
msg = None
try:
msg = self.sink.recv(0) # Use blocking or zmq.NOBLOCK, still appears to be slow
except zmq.Error
... meaningful exception handle here
# This last step, when timed usually takes less than a millisecond to process
if msg:
msg_dict = utils.bytestream_to_dict(msg) # unpacking step (negligible)
if msg_dict:
self.parser.parse(msg_dict) # parser is a dict of callbacks also negligible
На стороне процесса C
zmq_init (4);
void *context = zmq_ctx_new ();
/* Connect the Sender */
void *vent = zmq_socket (context, ZMQ_PUSH);
int timeo = 0;
int timeo_ret = zmq_setsockopt(vent, ZMQ_SNDTIMEO, &timeo, sizeof(timeo));
if (timeo_ret != 0)
error("Failed to set ZMQ recv timeout because %s", zmq_strerror(errno));
int linger = 100;
int linger_ret = zmq_setsockopt(vent, ZMQ_LINGER, &linger, sizeof(linger));
if (linger_ret != 0)
error("Failed to set ZMQ linger because %s", zmq_strerror(errno));
if (zmq_connect (vent, vent_port) == 0)
info("Successfully initialized ZeroMQ ventilator on %s", vent_port);
else {
error("Failed to initialize %s ZeroMQ ventilator with error %s", sink_port,
zmq_strerror(errno));
ret = 1;
}
...
/* When a message needs to be sent it's instantly hitting this where msg is a char* */
ret = zmq_send(vent, msg, msg_len, ZMQ_NOBLOCK);
Вкл. docker на целевой 32-битной системе lstopo - -v --no-io
Machine (P#0 local=1019216KB total=1019216KB HardwareName="Freescale i.MX6 Quad/DualLite (Device Tree)" HardwareRevision=0000 HardwareSerial=0000000000000000 Backend=Linux LinuxCgroup=/docker/d2b0a3b3a5eedb7e10fc89fdee6e8493716a359597ac61350801cc302d79b8c0 OSName=Linux OSRelease=3.10.54-dey+g441c8d4 OSVersion="#1 SMP PREEMPT RT Tue Jan 28 12:11:37 CST 2020" HostName=db1docker Architecture=armv7l hwlocVersion=1.11.12 ProcessName=lstopo)
Package L#0 (P#0 CPUModel="ARMv7 Processor rev 10 (v7l)" CPUImplementer=0x41 CPUArchitecture=7 CPUVariant=0x2 CPUPart=0xc09 CPURevision=10)
Core L#0 (P#0)
PU L#0 (P#0)
Core L#1 (P#1)
PU L#1 (P#1)
Core L#2 (P#2)
PU L#2 (P#2)
Core L#3 (P#3)
PU L#3 (P#3)
depth 0: 1 Machine (type #1)
depth 1: 1 Package (type #3)
depth 2: 4 Core (type #5)
depth 3: 4 PU (type #6)
![lstopo](https://i.stack.imgur.com/luk5j.png)
РЕДАКТИРОВАТЬ:
Мы смогли убрать задержку на нашей целевой машине, отключив почти все другие рабочие потоки.