ホームページ  >  記事  >  バックエンド開発  >  Pythonのメソッドがスレッド内で使用できない問題の解決方法

Pythonのメソッドがスレッド内で使用できない問題の解決方法

黄舟
黄舟オリジナル
2017-07-27 16:04:472540ブラウズ

Pythonではメソッドを定義すると直接呼び出すことができますが、それを呼び出すためのスレッドを作成すると失敗する可能性があります。この現象は、システム操作に COM オブジェクトを使用する場合によく発生し、スレッドの形式で呼び出されます。

例外プロンプトは次のとおりです:

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 メカニズムを使用すると、2 つのコンポーネントがどのような種類のコンピュータで実行されているか、どのようなオペレーティング システムで実行されているか、コンポーネントがどのような言語でコンパイルされているかを気にすることなく相互に通信できるため、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 メソッドで使用すると、例外構文エラーと関連するプロンプトがスローされます。 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 リクエストは、ルーティングを通じて対応するハンドラーを呼び出し、スレッド内で実行されます。したがって、この場合、システム トラフィックが 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 を使用します。これら 2 つの統計は実際の状況に応じて選択してください。

以上がPythonのメソッドがスレッド内で使用できない問題の解決方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。