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)
MySQL DB驱动程序不是线程安全的.您正在从所有线程同时使用相同的游标.
尝试在每个线程中创建一个新连接,或者创建一个线程可以使用的连接池(例如,将它们保存在a Queue,每个线程get连接中,并put在完成时将其打包).