python:线程在守护进程中无法正常工作

时间:2013-12-05 15:40:36

标签: python multithreading

我正在编写将检查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]线程启动后,脚本停留在与谷歌的线程,等待它结束,这没有按预期工作。应该在剧本结尾处杀死它吗?

我应该使用多处理而不是多线程,为每个主机生成单独的进程吗?

2 个答案:

答案 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))