2017-02-02 9 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))' - 'TestService.testMethod' - это несвязанный метод. В этом вызове 'p.map' нет экземпляра' TestService'. Какой объект вы ожидаете выполнить с помощью этого метода? – user2357112

+0

Первоначально метод передается потоками видео, и он запускает ffmpeg и создает журналы. Я помещаю этот метод внутри класса, так как я думал, что он может запутаться в проблеме области, но он все еще работает в одной и той же проблеме, этот метод вполне может быть определен вне класса без себя, и он столкнется с теми же проблемами, что и сейчас. , –

ответ

0

Есть две проблемы в вашем коде:

  • вы указываете map к TestService.testMethod, который является "несвязанным функция", которая живет в Пространство имен классов, но testMethod определено как метод класса. Вам необходимо либо вызвать его с self.testMethod или удалить self из определения функции
  • вы пытаетесь добавить Int в строку, используйте 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

Проблема была вызвана известной проблемой с pyinstaller и однофайлами в Windows.

Добавление следующей 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 для более подробной информации