不同的进程在 netstat 中显示为相同的 PID [英] Different processes showed as same PID within netstat
问题描述
我使用 Python 多处理模块生成了几个进程.但是,当我调用 netstat -nptl 时,每个 ip:port 侦听器都列在同一 PID 下.
I spawn few processes using the Python multiprocessing module. However when I call netstat -nptl, each ip:port listeners listed under the same PID.
我在 Ubuntu 14.04 上使用 Python 2.7.
I'm using Python 2.7 on Ubuntu 14.04.
netstat -V
>> net-tools 1.60
>> netstat 1.42 (2001-04-15)
相关代码:
import unittest
import multiprocessing
import socket
import os
import time
import ex1
class Listener(multiprocessing.Process):
def __init__(self, _ttl):
super(Listener, self).__init__()
self.ttl = _ttl
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(('localhost', 0))
def get_pid(self):
return self.pid
def get_name(self):
return self.socket.getsockname()
def run(self):
self.socket.listen(1)
time.sleep(self.ttl)
def listen(self):
self.start()
class TestEx1(unittest.TestCase):
def test_is_legal_ip(self):
# Legal IP
assert(ex1.is_legal_ip("1.1.1.1:55555"))
assert(ex1.is_legal_ip("0.1.1.255:55555"))
assert(ex1.is_legal_ip("0.0.0.0:55555"))
assert(ex1.is_legal_ip("255.255.255.255:55555"))
assert(ex1.is_legal_ip("0.1.2.3:55555"))
# Illegal IP
assert(not ex1.is_legal_ip("256.1.1.1:55555"))
assert(not ex1.is_legal_ip("1.256.1:55555"))
assert(not ex1.is_legal_ip("1.1.1.1.1:55555"))
assert(not ex1.is_legal_ip("1.a.1.1:55555"))
assert(not ex1.is_legal_ip("1.1001.1.1:55555"))
def test_address_to_pid(self):
# Create 3 listener processes
listener1 = Listener(22)
listener2 = Listener(22)
listener3 = Listener(22)
# Start listening
listener1.listen()
listener2.listen()
listener3.listen()
print listener1.get_pid()
print listener2.get_pid()
print listener3.get_pid()
# For each listener, get appropriate ip:port
address1 = str(str(listener1.get_name()[0])) + \
":" + str(listener1.get_name()[1])
address2 = str(str(listener2.get_name()[0])) + \
":" + str(listener2.get_name()[1])
address3 = str(str(listener3.get_name()[0])) + \
":" + str(listener3.get_name()[1])
# Check if address_to_pid() works as expected.
#assert(str(ex1.address_to_pid(address1)) == str(listener1.get_pid()))
#assert(str(ex1.address_to_pid(address2)) == str(listener2.get_pid()))
#assert(str(ex1.address_to_pid(address3)) == str(listener3.get_pid()))
# Waits for the listener processes to finish
listener2.join()
listener2.join()
listener3.join()
if __name__ == "__main__":
unittest.main()
输出:
4193
4194
4195
..
----------------------------------------------------------------------
Ran 2 tests in 22.019s
OK
Netstat -nptl 输出:
Netstat -nptl output:
(Not all processes could be identified, non-owned process info
will not be shown, you would have to be root to see it all.)
Active Internet connections (servers and established)
Proto Recv-Q Send-Q Local Address Foreign Address State PID/Program name
tcp 0 0 127.0.1.1:53 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:631 0.0.0.0:* LISTEN -
tcp 0 0 127.0.0.1:37529 0.0.0.0:* LISTEN 4192/python
tcp 0 0 127.0.0.1:53402 0.0.0.0:* LISTEN 4192/python
tcp 0 0 127.0.0.1:49214 0.0.0.0:* LISTEN 4192/python
tcp 1 0 192.168.46.136:49475 209.20.75.76:80 CLOSE_WAIT 2968/plugin_host
tcp 70 0 192.168.46.136:60432 91.189.92.7:443 CLOSE_WAIT 3553/unity-scope-ho
tcp6 0 0 ::1:631 :::* LISTEN -
推荐答案
使用我的 Mac OS 10.9.5 (Python 2.7.3),我可以重现相同的行为.经过几次尝试和错误,结果证明这是因为套接字对象在进程之间共享.(lsof -p
有助于识别监听套接字.)
Using my Mac OS 10.9.5 (Python 2.7.3), I could reproduce the same behavior. After several try-and-error, it turned out that it's because the socket objects are shared among the processes. (lsof -p <pid>
helps to identify listening sockets.)
当我对 Listener
类进行以下更改时,每个进程开始通过自己的 PID 侦听自己的端口号.
When I made following change to Listener
class, each process started to listen on its own port number by its own PID.
def get_name(self):
# this method cannot refer to socket object any more
# self.sockname should be initialized as "not-listening" at __init__
return self.sockname
def run(self):
# Instantiate socket at run
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
self.socket.bind(('localhost', 0))
self.sockname = self.socket.getsockname()
# Listener knows sockname
print self.sockname
self.socket.listen(1)
time.sleep(self.ttl)
此行为应该与 Ubuntu 的 Python 和 netstat 相同.
This behavior should be the same as Ubuntu's Python and netstat.
self.sockname 在原始进程中保持不听"
要作为独立进程监听端口,需要在监听器对象的run
方法中创建套接字(新进程在创建对象副本后调用此方法).但是在新进程中这个复制对象中更新的变量不会反映到原进程中的原始对象中.
To listen on port as independent process, sockets need to be created at run
method of a Listener object (New process calls this method after creating copy of the object). However variables updated in this copied object in the new process are not reflected to the original objects in original process.
这篇关于不同的进程在 netstat 中显示为相同的 PID的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!