Рекомендую перезапустить тест с простым python или ipython (без консоли). Также ограничьте счет одним процессом с помощью lsof -p <pid>
, чтобы исключить ненужные помехи от других процессов на вашем компьютере (эти файлы сокетов Unix 1375 в вашем тесте).
Вот простой тестовый скрипт:
import os
pid = os.getpid()
count=0
def lsof():
global count
count += 1
print(count,':')
os.system("lsof -p {0:d} 2>/dev/null | grep -E 'unix|IPv4|IPv6'".format(pid)) # -U doesn't work togeter with -p option
# Alternatively, you can use "lsof -U 2>/dev/null | grep -E {0:d}"
# but only unix socket file will be listed.
import zmq
c = zmq.Context();lsof()
tcp = c.socket(zmq.PUSH);lsof()
unix = c.socket(zmq.PUSH);lsof()
print('--- To bind ---')
tcp.bind('tcp://127.0.0.1:19413');lsof()
unix.bind('ipc://filename');lsof()
print('--- To close ---')
tcp.close();lsof()
unix.close();lsof()
Ниже приведен результат теста в моей среде (python 3.6.6, pyzmq 17.1.2, с Anaconda в CentOS 7).
1 :
2 :
3 :
--- To bind ---
4 :
ZMQbg/1 284018 gdlmx 13u IPv4 49443178 0t0 TCP localhost:19413 (LISTEN)
5 :
ZMQbg/1 284018 gdlmx 13u IPv4 49443178 0t0 TCP localhost:19413 (LISTEN)
ZMQbg/1 284018 gdlmx 14u unix 0xffff9cd6c5bf4800 0t0 49443204 filename
--- To close ---
6 :
ZMQbg/1 284018 gdlmx 14u unix 0xffff9cd6c5bf4800 0t0 49443204 filename
7 :
Я использовал python и ipython для запуска скрипта и получил тот же результат.
Итак, файл сокета или сетевой порт открыт только при вызове socket.bind
. Во время моих тестов никакие другие сокеты не открывались процессами python / ipython.
Обновление
В ответ на обновление ПО:
Ненормальное (неожиданное) поведение, вероятно, вызвано предварительно собранными двоичными файлами, включенными в пакет pyzmq в PyPI. pip install pyzmq
загрузит этот дистрибутив tar ball из PyPI, который содержит следующие предварительно скомпилированные двоичные файлы:
zmq/backend/cython:
_device.so _proxy_steerable.so constants.so error.so socket.so
_poll.so _version.so context.so message.so utils.so
zmq/.libs:
libzmq-39117701.so.5.2.1 libsodium-72341b7d.so.23.2.0
Чтобы быть совместимыми с максимально возможным количеством ОС Linux, эти двоичные файлы создаются в очень старой ОС (CentOS 5) в среде докера, называемой manylinux .
Anaconda использует другой подход для предварительной сборки двоичных файлов и содержит все зависимости в папке conda/envs
. Таким образом, их двоичные файлы построены в относительно современной среде.
Я протестировал двоичные файлы PyPI на моем компьютере с CentOS 7 с помощью приведенного выше сценария. Я могу подтвердить, что ZeroMQ открывает некоторые «фоновые» сокеты (2 сокета после создания контекста и 8 после первого создания сокета). Хотя мои тесты ниже показывают, что они используются для связи между потоками для внутренних механизмов ZeroMQ, лучше обратиться напрямую к сопровождающим пакета PyPI .
Вы также можете попытаться заставить pip
/ setuptools
собрать ZeroMQ для вашей ОС:
sudo yum install libzmq3-devel # RHEL-based
pip install --no-use-wheel pyzmq
# Use `--no-binary :all:` instead of `--no-use-wheel` in pip >= 10.0.0
Это может избавить от фоновых сокетов, если вы этого хотите.
Какое назначение фоновых розеток?
ZeroMQ внутренне использует несколько потоков для операции ввода-вывода. Количество потоков можно настроить с помощью IO_THREADS . Я считаю, что это число влияет на количество используемых сокетов. Проверьте это с
num_io_threads = int(sys.argv[1])
c = zmq.Context()
c.set(zmq.IO_THREADS,num_io_threads)
s = c.socket(zmq.PUSH)
lsof()
Вы найдете, что number_of_sockets
= 6 + 2 * num_io_threads
. Таким образом, я постулирую, что двоичные файлы ZeroMQ из PyPI внутренне используют сокеты для связи между потоками между основным потоком и рабочим / IO-потоками.