Multithreading 如何在后台运行tshark命令并在python中使用子进程退出它
我想在连接到telnet上的远程主机设备时,使用Wireshark的命令行风格Multithreading 如何在后台运行tshark命令并在python中使用子进程退出它,multithreading,python-2.7,subprocess,background-process,tshark,Multithreading,Python 2.7,Subprocess,Background Process,Tshark,我想在连接到telnet上的远程主机设备时,使用Wireshark的命令行风格tshark,进行数据包捕获。我想调用我为捕获而编写的函数: 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+'.p
tshark
,进行数据包捕获。我想调用我为捕获而编写的函数:
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\u new\u 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()
我想知道,当我想停止进程时,如何让它停止(比如可以添加退出条件,以便退出线程执行)。我尝试的上述代码似乎不起作用。线程化.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()
可能问题在于,如中所述,
setDaemon()
被忽略:主线程不是守护线程,因此在主线程中创建的所有线程默认为daemon=False。当没有活动的非守护进程线程时,整个Python程序就会退出。@LuisMuñoz我错过了这一部分。也许这就是为什么它不在后台运行。但是,我想知道是否有替代线程化的方法。这方面有什么线索吗?不幸的是,在python上没有太多的线程经验。也许从辅助线程启动该线程会有所帮助。向popen请求pid,然后简单地杀死它怎么样?