Python池代码未运行

时间:2017-02-02 21:44:26

标签: python multiprocessing python-multiprocessing pool

我正在使用多个过程编写Windows服务,并且我遇到了在池中调用的方法的问题。

现在我能够安装服务并运行它,它会将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)

2 个答案:

答案 0 :(得分: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()

P.S。尝试下次发布一个最小的代码示例:将代码删除到产生错误的最低限度。我发布的代码片段足以解释这个问题。通过这种方式,读者可以更容易理解,并且您可以更快地得到答案。

答案 1 :(得分: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