Python线程测试不工作
编辑 我通过分叉进程而不是使用线程解决了这个问题。从评论中的评论和链接来看,我认为线程化不是正确的做法 谢谢大家的帮助 完成编辑 我以前在线程方面做得不多。我已经创建了一些简单的示例Hello World脚本,但实际上没有任何效果 为了帮助我掌握它,我使用Nagios的二进制文件编写了一个简单的脚本来查询HTTP等服务。此脚本可以工作,但超时时间为1秒。如果我有10个服务超时,则脚本将花费超过10秒的时间 我要做的是并行运行所有检查。这将减少完成所需的时间 我现在有很多缺点,但不是一直都有。奇怪的是,当我在processCheck函数中检查主机时,我可以打印出所有主机。但在检查主机之后,hosts变量只打印集中的一个或两个主机。我觉得这是一个名称空间问题,但我不确定如何解决 我已经在这里发布了完整的代码,没有MySQL数据库,但是服务列表视图的结果如下所示 非常感谢您的帮助Python线程测试不工作,python,multithreading,Python,Multithreading,编辑 我通过分叉进程而不是使用线程解决了这个问题。从评论中的评论和链接来看,我认为线程化不是正确的做法 谢谢大家的帮助 完成编辑 我以前在线程方面做得不多。我已经创建了一些简单的示例Hello World脚本,但实际上没有任何效果 为了帮助我掌握它,我使用Nagios的二进制文件编写了一个简单的脚本来查询HTTP等服务。此脚本可以工作,但超时时间为1秒。如果我有10个服务超时,则脚本将花费超过10秒的时间 我要做的是并行运行所有检查。这将减少完成所需的时间 我现在有很多缺点,但不是一直都有。奇怪
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()
MySQL DB驱动程序不是线程安全的。您在所有线程中同时使用同一个游标
尝试在每个线程中创建一个新连接,或者创建一个线程可以使用的连接池,例如,将它们保持在队列中,每个线程获得一个连接,完成后将其打包。MySQL DB驱动程序不是线程安全的。您在所有线程中同时使用同一个游标
尝试在每个线程中创建一个新连接,或者创建一个线程可以使用的连接池,例如,将它们保持在队列中,每个线程都会获得一个连接,并在完成后将其打包。您应该先构建和填充队列。构建和填充整个队列后,您应该构建多个线程,每个线程在循环中轮询队列并处理队列上的项目。您应该首先构建和填充队列。当构建和填充整个队列时,您应该构建多个线程,每个线程在一个循环中轮询队列并处理队列上的一个项目。您意识到Python并不像您在多核处理器上期望的那样执行真正的多线程:
不要期望这10件事每件都花1秒钟。此外,即使在真正的多线程中,也有一些线程相关的开销。我想补充一点,这并不是对Python的污蔑。您意识到Python并没有像您在多核处理器上所期望的那样实现真正的多线程:
不要期望这10件事每件都花1秒钟。此外,即使在真正的多线程中,也有一些线程相关的开销。我想补充一点,这并不是对Python的污蔑。您使用的是什么操作系统/平台?请记住,由于全局解释器锁,Python实际上无法进行并发操作。有关详细信息,请参阅。@qid-仅适用于Python字节码,不适用于外部C代码或任何类型的阻止代码,例如DB Access。此外,您应该使用参数化查询,而不是将文本转换为字符串文本。没有借口,用Python/DB-API真的很容易。@Seth。请用问题的形式回答这个问题。只是个问题。所有的事实。然后——如果你愿意——分别回答你自己的问题。不要对这个问题闭口不谈。只需创建一个问题和一个答案。您使用的是什么操作系统/平台?请记住,由于全局解释器锁,Python实际上无法进行并发操作。有关详细信息,请参阅。@qid-仅适用于Python字节码,不适用于外部C代码或任何类型的阻止代码,例如DB Access。此外,您应该使用参数化查询,而不是将文本转换为字符串文本。没有借口,用Python/DB-API真的很容易。@Seth。请用问题的形式回答这个问题。只是个问题。所有的事实。然后——如果你愿意——分别回答你自己的问题。不要对这个问题闭口不谈。创建一个问题和一个答案。谢谢。我已经更改了代码,每次启动新连接时都会出现相同的问题。命令模块是否可能不是线程安全的?这似乎就是问题所在。如果命令模块不是线程安全的,我会感到惊讶,但无论如何,它已被弃用-首选子流程模块。谢谢。我已经更改了代码,每次启动新连接时都会出现相同的问题。命令模块是否可能不是线程安全的?这似乎就是问题所在。如果命令模块不是线程安全的,我会感到惊讶,但在任何情况下,它都不推荐使用-首选子流程模块。感谢提供的信息。多愁善感
你认为为每一张支票创建一个叉子会有效吗?据我所知,每个分叉都应该认为是独立的。因为它在与MySQL对话,所以我不需要来回传递任何变量。@wheaties-仅用于Python字节码。访问数据库并运行子进程可以释放GIL,Python代码本身在这里并不慢,因此他应该得到线性加速,例如总共1秒。感谢您提供的信息。你认为为每一张支票创建一个分叉行行吗?据我所知,每个分叉都应该认为是独立的。因为它在与MySQL对话,所以我不需要来回传递任何变量。@wheaties-仅用于Python字节码。访问数据库并运行子进程可以释放GIL,而Python代码本身在这里并不慢,因此他应该得到线性加速,例如总共1秒。