关于python方法无法在线程中使用的解决办法
异常提示如下:
syntax error。WMI returned a syntax error: you're probably running inside a thread without first calling pythoncom.CoInitialize[Ex] (no underlying exception)
仔细观察的话,异常提示中已经给出了解决方案。在运行一个线程的时候需要调用pythoncom.CoInitialize()方法。鄙人在程序中使用了WMI模块,试图获取部分系统信息。
异常的原因(推测)是com的机制问题。由于COM机制允许任意两组件之间相互通信而不必关心是在何种计算机上的何种操作系统下运行,也不用关心组件是使用何种语言编制的,这使COM技术拥有了强大的生命力。初始化COM环境的目的是使调用COM的API工作正常,也就是在COM操作之前调用CoInitialize或CoInitializeEX所以在线程函数中,如果使用com对象就必须调用CoInitialize或CoInitializeEX ,同时在退出时使用CoUninitialize来释放对象。
案例:
c === send = 0.0 t += float(t.BytesReceivedPersec) / 1024 / 1024+= float(t.BytesSentPersec) / 1024 / 1024 rec, send
这段代码是根据电脑的网卡获取上下行的流量(即发送流量和接收流量),直接运行是可以的。但是在tornado的RequestHandler的get或者post方法中使用时,会抛出异常syntax error及相关提示。在RequestHandler中,post或者get请求被认为是一个后台的线程方法,所以需要在实例化WMI这个com组件之前先进行com实例化。
为什么RequestHandler中post或者get请求被认为是一个后台的线程方法?这个问题从使用tornado的代码中可以窥得一二。代码如下:
if __name__ == '__main__': app = tornado.web.Application( handlers=[(r"/test/(\w+)", testHandler), (r'/', MainHandler)] ) server = tornado.httpserver.HTTPServer(app) server = server.listen(8848) tornado.ioloop.IOLoop.instance().start();
在给tornado配置了路由规则之后,我们开启了httpserver的服务,最后创建进程来使tornado运行起来。而每次的post或者get请求则是通过路由调用相应的Handler,这些都是在线程中执行的。故案例中通过com组件WMI来获取系统流量放在get方法中就会报错。修改后如下:
def get(self): res = {} pythoncom.CoInitialize() c = wmi.WMI() interfaces = c.Win32_PerfRawData_Tcpip_NetworkInterface() print len(interfaces) rec = send = 0.0 for t in interfaces: print t.Name rec += float(t.BytesReceivedPersec) / 1024 / 1024 send += float(t.BytesSentPersec) / 1024 / 1024 print rec, send res["receive"] = "%.2f" % rec res["send"] = "%.2f" % send self._write_json(res)
模块中很有很多类型(类型也有很多属性),在具体使用的过程中查询起来很痛苦。案例中的统计流量用的是Win32_PerfRawData_Tcpip_NetworkInterface ,也有解决方案用的是Win32_PerfRawData_Tcpip_TCPv4 两个统计到的数据差别很大,请根据实际情况来选择。
以上就是关于python方法无法在线程中使用的解决办法的详细内容,更多请关注其它相关文章!
推荐阅读
-
在Python中操作列表之list.extend()方法的使用
-
使用python中的in ,not in来检查元素是不是在列表中的方法
-
在Python中操作文件之truncate()方法的使用教程
-
在Python程序中操作文件之flush()方法的使用教程
-
在Python程序中操作文件之isatty()方法的使用教程
-
在Python中操作文件之seek()方法的使用教程
-
在Python中操作文件之read()方法的使用教程
-
[python] 在 python2和3中关于类继承的 super方法简要说明
-
在IOS中为什么使用多线程及多线程实现的三种方法
-
在Python中操作时间之mktime()方法的使用教程