Maison >développement back-end >Tutoriel Python >Solution au problème selon lequel les méthodes Python ne peuvent pas être utilisées dans les threads

Solution au problème selon lequel les méthodes Python ne peuvent pas être utilisées dans les threads

黄舟
黄舟original
2017-07-27 16:04:472657parcourir

En python, définir une méthode peut être appelée directement, mais créer un thread pour l'appeler peut provoquer un échec. Ce phénomène se produit souvent lors de l'utilisation d'objets COM pour des opérations système et est appelé sous forme de threads.

L'invite d'exception est la suivante :

syntax error。WMI returned a syntax error: you're probably running inside a thread without first calling pythoncom.CoInitialize[Ex] (no underlying exception)

Si vous observez attentivement, la solution a été donnée dans l'invite d'exception. Lors de l'exécution d'un thread, vous devez appeler la méthode pythoncom.CoInitialize(). J'ai utilisé le module WMI dans mon programme pour essayer d'obtenir des informations système.

La cause de l'exception (présumée) est un problème de mécanisme COM. Étant donné que le mécanisme COM permet à deux composants de communiquer entre eux sans avoir à se soucier du type d'ordinateur sur lequel ils s'exécutent, du système d'exploitation sur lequel ils s'exécutent ou de la langue dans laquelle le composant est compilé, cela rend COM technologie puissante vitalité. Le but de l'initialisation de l'environnement COM est de faire fonctionner correctement l'API appelant COM, c'est-à-dire d'appeler CoInitialize ou CoInitializeEX avant l'opération COM. Par conséquent, dans la fonction thread, si vous utilisez l'objet COM, vous devez appeler CoInitialize ou CoInitializeEX. , et utilisez CoUninitialize pour libérer l'objet en quittant .
Cas :


c === send = 0.0 t += float(t.BytesReceivedPersec) / 1024 / 1024+= float(t.BytesSentPersec) / 1024 / 1024 rec, send

Ce code permet d'obtenir du trafic montant et descendant en fonction de la carte réseau de l'ordinateur (c'est-à-dire envoyer trafic et recevoir du trafic), vous pouvez exécuter directement. Cependant, lorsqu'il est utilisé dans la méthode get ou post du RequestHandler de tornado, une erreur de syntaxe d'exception et les invites associées seront générées. Dans RequestHandler, la requête post ou get est considérée comme une méthode de thread d’arrière-plan, donc com doit être instancié avant d’instancier le composant WMI com.

Pourquoi la demande de publication ou d'obtention dans RequestHandler est-elle considérée comme une méthode de fil de discussion en arrière-plan ? Ce problème peut être vu à partir du code utilisant tornado. Le code est le suivant :


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();

Après avoir configuré les règles de routage pour tornado, nous avons démarré le service httpserver, et finalement créé un processus pour exécuter tornado. Chaque demande de publication ou d'obtention appelle le gestionnaire correspondant via un routage, qui est exécuté dans le thread. Par conséquent, dans le cas où le trafic système est obtenu via le composant com WMI et placé dans la méthode get, une erreur sera signalée. La modification est la suivante :


    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)

Il existe de nombreux types dans le module (les types ont également de nombreux attributs), ce qui est très pénible à interroger lors d'une utilisation spécifique. Le trafic statistique dans ce cas utilise Win32_PerfRawData_Tcpip_NetworkInterface, et il existe également des solutions qui utilisent Win32_PerfRawData_Tcpip_TCPv4. Veuillez choisir en fonction de la situation réelle.

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn