2017-02-02 10 views
1

私はマルチプロセッシングを使用してWindowsサービスを作成していますが、プールで呼び出されたメソッドに問題があります。Pythonプールコードが実行されていません

サービスをインストールして実行すると、The service started running...がログファイルに出力されますが、それ以外は何も出力されません。

プロセスエクスプローラ(下のスクリーンショットを参照)を見ると、プロセスが作成されて絶えず終了しているのがわかりますが、TestMethod内のコードは実行されておらず、サービスはプールを終了しませんelseがファイルに書き込まれています。

サービスがプールに滞留し、停止イベントのチェックに達しないため、サービスを停止できません。

TestMethod内のコードがまったく実行されないのはなぜですか?

Process Explorer Screenshot

サービスコード:

import servicemanager 
import win32event 
import win32service 
import win32serviceutil 
import multiprocessing 


class TestService(win32serviceutil.ServiceFramework): 
    _svc_name_ = "TestService" 
    _svc_display_name_ = "Test Service" 

    def testMethod(self, testVar): 

     with open('C:\\Test.log', 'a') as f: 
      f.write('The method is running: ' + testVar) 
      f.close() 

    def __init__(self, args): 

     win32serviceutil.ServiceFramework.__init__(self, args) 
     self.hWaitStop = win32event.CreateEvent(None, 0, 0, None) 
     socket.setdefaulttimeout(60) 

    def SvcStop(self): 

     self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
     win32event.SetEvent(self.hWaitStop) 

    def SvcDoRun(self): 

     with open('C:\\Test.log', 'a') as f: 
      f.write('The service started running...\n') 
      f.close() 

     rc = None 

     p = multiprocessing.Pool(5) 

     p.map(TestService.testMethod, range(1,6)) 

     with open('C:\\Test.log', 'a') as f: 
      f.write('Finished method...\n') 
      f.close() 

     while rc != win32event.WAIT_OBJECT_0:     
      with open('C:\\Test.log', 'a') as f: 
       f.write('The service is running...\n') 
       f.close() 
      rc = win32event.WaitForSingleObject(self.hWaitStop, 5000) 

     with open('C:\\Test.log', 'a') as f: 
       f.write('StreamCapture service stopped.\n') 
       f.close() 



if __name__ == '__main__': 
    if len(sys.argv) == 1: 
     servicemanager.Initialize() 
     servicemanager.PrepareToHostSingle(TestService) 
     servicemanager.StartServiceCtrlDispatcher() 
    else: 
     win32serviceutil.HandleCommandLine(TestService) 
+0

'p.map(TestService.testMethod、範囲(1,6))'のためhttps://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessingを参照してください - 'TestService.testMethod'はバインドされていないメソッドです。この 'p.map'呼び出しには' TestService'のインスタンスはありません。このメソッドを実行するには、どのオブジェクトが必要ですか? – user2357112

+0

元々、このメソッドはビデオストリームに渡され、ffmpegを実行してログを作成します。私はそれがスコープの問題に遭遇する可能性があると思ったので、クラスの中にメソッドを入れましたが、それはまだ同じ問題に走っています。メソッドは自分自身なしでクラスの外で定義でき、 。 –

答えて

0

あなたのコード内の二つの問題があります

  • あなたはTestService.testMethodmapを指し、に住んでいる "結合していない機能" でありますクラスネームスペースですが、testMethodはクラスメソッドのように定義されています。あなたが修正使用f.write('The method is running: {}'.format(testVar))代わり

あなたのストリップダウンプログラムは、次のようになり、文字列にint型を追加しようとあなたのどちらかがself.testMethodでそれを呼び出す必要があるか、関数定義

  • からselfを削除します。

    import multiprocessing 
    
    class TestService: 
        def testMethod(self, testVar): 
         with open('C:\\Test.log', 'a') as f: 
          f.write('The method is running: {}'.format(testVar)) 
          f.close() 
    
        def SvcDoRun(self): 
         p = multiprocessing.Pool(5) 
         p.map(self.testMethod, range(1,6)) 
    
    
    if __name__ == "__main__": 
        d = TestService() 
        d.SvcDoRun() 
    

    PS次回に最小限のコード例を投稿してみてください:エラーを生成する最小限のコードにコードを分解してください。投稿したコードは問題を説明するのに十分なものでした。これにより、読者の理解が容易になり、より迅速な回答が得られます。

  • 0

    この問題は、Windowsのpyinstallerおよびonefile実行可能ファイルに関する既知の問題が原因で発生しています。

    私の輸入は私のためにそれを固定した後、次のtryブロックを追加:

    try: 
        # Python 3.4+ 
        if sys.platform.startswith('win'): 
         import multiprocessing.popen_spawn_win32 as forking 
        else: 
         import multiprocessing.popen_fork as forking 
    except ImportError: 
        import multiprocessing.forking as forking 
    

    は詳細

    関連する問題