不同的进程在 netstat 中显示为相同的 PID [英] Different processes showed as same PID within netstat

查看:50
本文介绍了不同的进程在 netstat 中显示为相同的 PID的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我使用 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆