2017-02-02 84 views
1

我正在寫與multiproccesing Windows服務,我運行到與被稱爲池中的方法問題。的Python代碼池沒有運行

現在我能夠安裝服務,並運行它,它輸出The service started running...日誌文件,但沒有別的。

看着進程資源管理器(見下面的屏幕截圖),我看到進程正在創建並不斷完成,但TestMethod內的代碼沒有運行,服務也沒有退出池,因爲沒有任何東西其他人正在寫入文件。

我不能停止該服務,因爲它停留在游泳池,沒有達到停止事件的檢查。

爲什麼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))' - 'TestService.testMethod'是一個未綁定的方法。在這個'p.map'調用中沒有'TestService'的實例。你期望執行這種方法的對象是什麼? – user2357112

+0

原來的方法傳遞視頻流和它運行的ffmpeg,並創建日誌。我把這個方法放在類裏面,因爲我認爲它可能會遇到一個範圍問題,但它仍然遇到了同樣的問題,這個方法可以非常好地在類之外定義而沒有自己,它會遇到與現在相同的問題。 –

回答

0

有兩個問題在你的代碼:

  • 你點mapTestService.testMethod,這是一個 「未綁定功能」 住在類的命名空間,但testMethod定義像一個類的方法。你要麼需要self.testMethod調用它,或者從函數定義
  • 您嘗試爲int添加到字符串中刪除的self,使用f.write('The method is running: {}'.format(testVar))代替

你的精簡程序,修正應該是這樣的:

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 

詳情請參閱https://github.com/pyinstaller/pyinstaller/wiki/Recipe-Multiprocessing