我正在编写将检查SSH连接的简单脚本,我无法理解,为什么它会挂在一个线程上。
class myThread(threading.Thread):
def __init__(self, hostname ):
threading.Thread.__init__(self)
self.hostname = hostname
def run(self):
return self.doSSH(self.hostname)
def doSSH(self,hostname):
s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
s.connect((hostname, 22))
result = s.recv(1024)
if re.findall(r'^SSH.+?SSH.+',result) :
return "Up"
else :
return "Down"
def main():
q = Queue.Queue()
completeHostlist = ["host1","host2","google.com","host3"]
for hostname in completeHostlist:
thread = myThread(hostname)
thread.daemon = True
q.put_nowait(thread.run())
q.get_nowait()
我不明白为什么这个脚本会挂在google.com上?我希望它能够生成守护程序线程并继续使用host3。一旦完成host3,它必须杀死与谷歌的线程并返回结果。我做错了什么?
我已经想出了run()和start()。无论如何,在所有主机[1-3]线程启动后,脚本停留在与谷歌的线程,等待它结束,这没有按预期工作。应该在剧本结尾处杀死它吗?
我应该使用多处理而不是多线程,为每个主机生成单独的进程吗?
答案 0 :(得分:2)
在您的代码中,您执行q.put_nowait(thread.run())
。这会立即在当前线程上运行ssh。您需要调用特定于线程的方法来启动线程。您需要致电thread.start()
。
不确定你在使用队列做什么。
答案 1 :(得分:1)
不要直接为任何线程调用.run()
方法。由@Sorin said代替thread.start()
。
您不需要定义新的线程类,在这种情况下函数就足够了:
from Queue import Queue
from threading import Thread
def is_ssh_up(result_queue, hostname, port=22):
# try to connect here
# ...
# write results
result_queue.put((hostname, True)) # Up
def main():
q = Queue()
hosts = ["host1", "host2", "google.com", "host3"]
for hostname in hosts: # start worker threads
t = Thread(target=is_ssh_up, args=[q, hostname])
t.daemon = True
t.start()
for _ in hosts: # collect results
hostname, is_up = q.get()
print("%s is %s" % (hostname, "Up" if is_up else "Down"))
或者您可以使用线程池:
from multiprocessing.pool import ThreadPool
def is_ssh_up(hostname, port=22):
# try to connect here
# ...
# return results
return hostname, is_up
hosts = ["host1", "host2", "google.com", "host3"]
pool = ThreadPool(20) # limit number of concurrent connections to 20
for hostname, is_up in pool.imap_unordered(is_ssh_up, hosts):
status = "Up" if is_up else "Down" if is_up is not None else "Unknown"
print("%s status is %s" % (hostname, status))