multithreading - 如何在后台运行 tshark 命令并使用 python 中的子进程退出它

标签 multithreading python-2.7 subprocess background-process tshark

我想使用 tshark 进行数据包捕获,Wireshark 的命令行风格,同时通过 telnet 连接到远程主机设备。我想调用我为捕获而编写的函数:

def wire_cap(ip1,ip2,op_fold,file_name,duration):  # invoke tshark to capture traffic during session
    if duration == 0:
        cmd='"tshark" -i 1 -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
    else:
        cmd='"tshark" -i 1 -a duration:'+str(duration)+' -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)

    p = subprocess.Popen(cmd, shell=True,stderr=subprocess.PIPE)
    while True:
        out = p.stderr.read(1)
        if out == '' and p.poll() != None:
            break
        if out != '':
            sys.stdout.write(out)
            sys.stdout.flush()

出于调试目的,我想通过在需要时调用它并在获得捕获时停止它来在后台运行此函数。就像是:
Start a thread or a background process called wire_capture
//Do something here
Stop the thread or the background process wire_capture

通过阅读,我意识到thread.start_new_thread()threading.Thread()似乎只有当我知道捕获的持续时间(退出条件)时才合适。我尝试使用 thread.exit()但它的行为就像 sys.exit()并完全停止了程序的执行。我也试过 threading.Event()如下:
if cap_flg:
    print "Starting a packet capture thread...."
    th_capture = threading.Thread(target=wire_cap, name='Thread_Packet_Capture', args=(IP1, IP2, output, 'wire_capture', 0, ))
    th_capture.setDaemon(True)
    th_capture.start()

.
.
.
.
.

if cap_flg:
    thread_kill = threading.Event()
    print "Exiting the packet capture thread...."
    thread_kill.set()
    th_capture.join()

我想知道当我想停止进程时如何停止它(就像可以添加退出条件以便我可以退出线程执行)。我试过的上面的代码似乎不起作用。

最佳答案

threading.Event()方法在正确的轨道上,但是您需要事件在两个线程中都可见,因此您需要在启动第二个线程之前创建它并将其传入:

if cap_flg:
    print "Starting a packet capture thread...."
    thread_kill = threading.Event()
    th_capture = threading.Thread(target=wire_cap, name='Thread_Packet_Capture', args=(IP1, IP2, output, 'wire_capture', 0, thread_kill))
    th_capture.setDaemon(True)
    th_capture.start()

在那while循环,让观察线程在每次迭代时检查事件,并停止循环(也可能终止它开始的 tshark),如果它被设置了。您还需要确保进程不会永远等待进程的输出,并忽略终止事件,仅在有数据可用时才从管道中读取:
def wire_cap(ip1,ip2,op_fold,file_name,duration,event):  # invoke tshark to capture traffic during session
    if duration == 0:
        cmd='"tshark" -i 1 -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)
    else:
        cmd='"tshark" -i 1 -a duration:'+str(duration)+' -P -w '+ op_fold+file_name+'.pcap src ' + str(ip1) + ' or src '+ str(ip2)

    p = subprocess.Popen(cmd, shell=True,stderr=subprocess.PIPE)
    while not event.is_set():
        # Make sure to not block forever waiting for 
        # the process to say things, so we can see if
        # the event gets set. Only read if data is available.
        if len(select.select([p.stderr], [], [], 0.1)) > 0:
            out = p.stderr.read(1)
            if out == '' and p.poll() != None:
                break
            if out != '':
                sys.stdout.write(out)
                sys.stdout.flush()
    p.kill()

然后实际上告诉线程停止你只需设置事件:
if cap_flg:
    print "Exiting the packet capture thread...."
    thread_kill.set()
    th_capture.join()

关于multithreading - 如何在后台运行 tshark 命令并使用 python 中的子进程退出它,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51629214/

相关文章:

C - pthread条件变量

python - 如何检查变量是整数还是字符串?

python - 根据列表中的值在 Python 中调用不同的函数

python - PermissionError : [WinError 5] Access denied

java - 如何使用多线程并行运行两个类?

java - 动态 ReentrantReadWriteLock-s 用于同步对大量对象的访问

multithreading - 进程和线程有什么区别?

python - 在带有嵌套字典的 Python 中,我应该检查类型吗?我还可以使用什么其他方法?

python - 在 Python 中创建目录然后打开其中的文件时出错,但如果目录已存在则不会出错

Python:subprocess.call 破管