什么解决方案不会从select中丢失任何PID?

问题描述

让我们说我有这种方法可以在python脚本中(从this tutorial扩展)继续收集新的PID及其基本信息(即仅nameexe) :

from select import select
from multiprocessing import Process
if PY3:
    from queue import Queue
else:
    from multiprocessing import Queue
...

def startNetlink(q):
    # Create Netlink socket
    s = socket.socket(socket.AF_NETLINK,socket.soCK_DGRAM,NETLINK_CONNECTOR)

    # Netlink sockets are connected with pid and message group mask,# message groups are for multicast protocols (like our process event
    # connector).

    try:
        # Need root/sudo to make this works
        s.bind((os.getpid(),CN_IDX_PROC))
    except socket.error as e: #(_errno,errmsg):
        if e.errno == errno.EPERM:
            print ("You don't have permission to bind to the "
                   "process event connector. Try sudo.")
            raise SystemExit(1)
        raise

    pec_control(s,listen=True)

    while True:
        (readable,w,e) = select([s],[],[])
        buf = readable[0].recv(256)

        event = pec_unpack(buf)

        if event != None: 
            event["what"] = process_events_rev.get(event.what)
            
            ql = filter_target_event(event)
            ql.__str__() # **MUST** call repr() or __str__() once to not get ._name is None
            # No need check None,we want asap
            # will .put affect the speed ?
            try:
                # [1] ql._ppid (prefix underscore) always None even though repr() ran
                # [2] .ppid(without prefix underscore)/.exe throws py2(.instancemethod) and py3(Rlock err)
                if ql:
                    ql_pid = ql._pid
                    ql_name = ql._name
                    try:
                        q.put( (ql_pid,ql_name,ql.exe()) )
                    except (AttributeError,except_no_such_process) as e:
                        q.put( (ql_pid,None) )
                # Can see strange ._name such as `StreamT~ns #251` and `StreamT~ns #384`
            except (AttributeError,except_no_such_process,except_access_denied) as e:
                pass 
                # test case: `for i in {1..1000}; do (pwd); done`
                # [1] psutil.NoSuchProcess process no longer exists (pid=799)
                # [2] 'nonetype' object has no attribute '_pid'
                # currently just let it GONE without any message bcoz only miss a little.

    s.close()

在其他调用者脚本中,使用psutil(基于基本信息nameexe的PID调用函数并对该进程进行进一步分析,因为一些进程很快就消失了,我需要知道该PID的最少信息):

import multiprocessing
if PY3:
    from queue import Empty
else:
    from Queue import Empty
...
q = multiprocessing.Queue()
p = multiprocessing.Process(target=startNetlink,args=(q,))
p.start()
while 1:
    if q:
        qv = q.get(block=False)
        ... cont.,use that pid,name,and exe for further real-time analysis

我尝试不遗漏任何进程,但是似乎不可能,因为我从(readable,e)获得select([s],[])到队列中与下一个队列之间存在延迟间隔 while循环。 如果某个过程太快而无法终止,那么该过程很可能会丢失。

什么解决方不会丢失select()中的任何PID?还是我必须使用其他方式来执行此操作,例如钩子?

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)