gpt4 book ai didi

Python - 无法使用 KeyboardInterrupt 终止主线程

转载 作者:太空狗 更新时间:2023-10-29 18:08:45 26 4
gpt4 key购买 nike

我正在制作一个简单的多线程端口扫描器。它扫描主机上的所有端口并返回打开的端口。问题在于中断扫描。扫描完成需要很长时间,有时我希望在扫描过程中用 C-c 终止程序。问题是扫描不会停止。主线程锁定在 queue.join() 上并且忽略了 KeyboardInterrupt,直到处理完队列中的所有数据,从而解除主线程阻塞并优雅地退出程序。我所有的线程都是守护进程,所以当主线程死掉时,它们应该和他一起死掉。

我尝试使用信号库,但没有成功。重写 threading.Thread 类并添加用于正常终止的方法不起作用...主线程在执行 queue.join() 时不会收到 KeyboardInterrupt

import threading, sys, Queue, socket

queue = Queue.Queue()

def scan(host):
while True:
port = queue.get()

if port > 999 and port % 1000 == 0:
print port
try:
#sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
#sock.settimeout(2) #you need timeout or else it will try to connect forever!
#sock.connect((host, port))
#----OR----
sock = socket.create_connection((host, port), timeout = 2)

sock.send('aaa')
data = sock.recv(100)
print "Port {} open, message: {}".format(port, data)
sock.shutdown()
sock.close()
queue.task_done()
except:
queue.task_done()


def main(host):
#populate queue
for i in range(1, 65536):
queue.put(i)
#spawn worker threads
for port in range(100):
t = threading.Thread(target = scan, args = (host,))
t.daemon = True
t.start()

if __name__ == '__main__':
host = ""

#does input exist?
try:
host = sys.argv[1]
except:
print "No argument was recivied!"
exit(1)

#is input sane?
try:
host = socket.gethostbyname(host)
except:
print "Adress does not exist"
exit(2)

#execute main program and wait for scan to complete
main(host)
print "Post main() call!"
try:
queue.join()
except KeyboardInterrupt:
print "C-C"
exit(3)

编辑:

我找到了使用时间模块的解决方案。

#execute main program and wait for scan to complete
main(host)

#a little trick. queue.join() makes main thread immune to keyboardinterrupt. So use queue.empty() with time.sleep()
#queue.empty() is "unreliable" so it may return True a bit earlier then intented.
#when queue is true, queue.join() is executed, to confirm that all data was processed.
#not a true solution, you can't interrupt main thread near the end of scan (when queue.empty() returns True)
try:
while True:
if queue.empty() == False:
time.sleep(1)
else:
break
except KeyboardInterrupt:
print "Alas poor port scanner..."
exit(1)
queue.join()

最佳答案

您已经将您的线程设为守护进程,但是您需要在守护线程存在时保持您的主线程处于事件状态,具体方法如下:Cannot kill Python script with Ctrl-C

关于Python - 无法使用 KeyboardInterrupt 终止主线程,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17991033/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com