Python线程测试不起作用

Jim*_*Jim 1 python multithreading

编辑

我通过分叉进程而不是使用线程解决了这个问题.从评论中的评论和链接,我不认为线程是正确的举动.

谢谢大家的帮助.

完成编辑

我之前没有做太多线程.我已经创建了一些简单的示例"Hello World"脚本,但实际上没有任何工作.

为了帮助我掌握它,我使用Nagios中的二进制文件编写了一个简单的脚本来查询HTTP等服务.如果我有10个服务超时,则此脚本可以正常工作,但超时为1秒,脚本将花费超过10秒的时间.

我想要做的是彼此并行运行所有检查.这应该减少完成所需的时间.

我目前正在收到段错误,但不是所有时间.奇怪的是,我在processCheck函数中检查主机,我可以打印出所有主机.在检查主机之后,hosts变量仅打印集合中的一个或两个主机.我觉得这是命名空间问题,但我不确定如何解决.

我在这里发布了整个代码没有MySQL数据库,但是他的service_list视图的结果看起来像.

非常感谢任何帮助.

6543L, 'moretesting.com', 'smtp')
(6543L, 'moretesting.com', 'ping')
(6543L, 'moretesting.com', 'http')


from commands import getstatusoutput
import MySQLdb
import threading
import Queue
import time

def checkHost(x, service):
    command = {}
    command['http'] = './plugins/check_http -t 1 -H '
    command['smtp'] = './plugins/check_smtp -t 1 -H '

    cmd = command[service]
    cmd += x
    retval = getstatusoutput(cmd)
    if retval[0] == 0:
        return 0
    else: 
        return retval[1]

def fetchHosts():
    hostList = []
    cur.execute('SELECT veid, hostname, service from service_list')
    for row in cur.fetchall():
        hostList.append(row)
    return hostList

def insertFailure(veid, hostname, service, error):
    query = 'INSERT INTO failures (veid, hostname, service, error) '
    query += "VALUES ('%s', '%s', '%s', '%s')" % (veid, hostname, service, error)
    cur.execute(query)
    cur.execute('COMMIT')


def processCheck(host):
    #If I print the host tuple here I get all hosts/services
    retval = checkHost(host[1], host[2])
    #If I print the host tuple here, I get one host maybe two
    if retval != 0:
        try:
            insertFailure(host[0], host[1], host[2], retval)
        except:
            pass
    else:
        try:
            #if service is back up, remove old failure entry
            query = "DELETE FROM failures WHERE veid='%s' AND service='%s' AND hostname='%s'" % (host[0], host[2], host[1])
            cur.execute(query)
            cur.execute('COMMIT')
        except:
            pass
    return 0

class ThreadClass(threading.Thread):

    def __init__(self, queue):
        threading.Thread.__init__(self)
        self.queue = queue

    def run(self):
        processCheck(queue.get())
        time.sleep(1)

def main():
    for host in fetchHosts():
        queue.put(host)
        t = ThreadClass(queue)
        t.setDaemon(True)
        t.start()

if __name__ == '__main__':
    conn = MySQLdb.connect('localhost', 'root', '', 'testing')
    cur = conn.cursor()
    queue = Queue.Queue()
    main()
    conn.close()
Run Code Online (Sandbox Code Playgroud)

ori*_*rip 8

MySQL DB驱动程序不是线程安全的.您正在从所有线程同时使用相同的游标.

尝试在每个线程中创建一个新连接,或者创建一个线程可以使用的连接池(例如,将它们保存在a Queue,每个线程get连接中,并put在完成时将其打包).