Python,pywin32,Windows服务和多处理

时间:2012-04-12 13:39:23

标签: python windows-services pywin32

我正在使用python 2.6,pywin32 build 217和Windows 7。

我创建了一个Windows服务,如下所示:

class Service(win32serviceutil.ServiceFramework):

    _svc_name_ = 'MPTESTER'
    _svc_display_name_ = 'MP TESTER'
    _svc_description_ = "NA"
    _scratch_workspace_ = os.environ["TEMP"]
    _process_count_ = (int(os.environ["NUMBER_OF_PROCESSORS"]) *2) -1
    _pool_ = None
    def __init__(self, *args):
        win32serviceutil.ServiceFramework.__init__(self, *args)
        self.log('init')
        self.runFlag = True
        self.stop_event = win32event.CreateEvent(None, 0, 0, None)
    def log(self, msg):
        import servicemanager
        servicemanager.LogInfoMsg(str(msg))
    def sleep(self, sec):
        win32api.Sleep(sec*1000, True)
    def SvcDoRun(self):
        self.ReportServiceStatus(win32service.SERVICE_START_PENDING)
        try:
            self.ReportServiceStatus(win32service.SERVICE_RUNNING)
            self.log('start')
            self.start()
            while self.runflag == True:
                pass
            self.log('wait')
            win32event.WaitForSingleObject(self.stop_event, win32event.INFINITE)
            self.log('done')
        except Exception, x:
            self.log('Exception : %s' % x)
            self.SvcStop()
    def SvcStop(self):
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING)
        self.log('stopping')
        self.stop()
        self.log('stopped')
        win32event.SetEvent(self.stop_event)
        self.ReportServiceStatus(win32service.SERVICE_STOPPED)
    def start(self):
        dummyFilePath = r"c:\temp\errorLog.log"
        with open(dummyFilePath,'w') as dummy:
            #pythonFile = os.path.basename(str(inspect.getfile(inspect.currentframe())))
            #scriptPath = str(inspect.getfile(inspect.currentframe())).replace(os.sep + pythonFile,"")
            dummy.write('test 1\n')
            dummy.flush()
            pythonExe = os.path.join(sys.exec_prefix, 'python.exe')
            multiprocessing.set_executable(pythonExe)
            dummy.write('test 2\n')
            dummy.flush()
            if self.runFlag == None:
                self.runFlag = True
            dummy.write('test 3\n')
            dummy.flush()
            while self.runFlag:
                dummy.write('test 4\n')
                dummy.flush()
                results = []
                pool = multiprocessing.Pool((int(os.environ["NUMBER_OF_PROCESSORS"]) *2) -1)
                dummy.write("After POOL CREATED")
                dummy.flush()
                for i in range(self._process_count_):
                    dummy.write('test in range \n')
                    dummy.flush()
                    results.append(pool.apply_async(someLongFunction, 
                                                   [r"c:\temp",
                                                    "test_" + str(i) + ".txt"
                                                         ] ))

                #    Wait for all processes to finish
                #
                pool.close()
                pool.join()
                dummy.write("WAITING TO FINISH!")
                dummy.flush()
                #    delete the references
                #
                del results
                del pool
                dummy.write('fin test \n')
                dummy.flush()
                self.stop()
                break
    def stop(self): 
        self.runFlag = False

我的问题是多处理实例永远不会触发。有没有办法让多处理模块工作?我可以使用子处理,但我真的不想要维护两个python文件。

由于

1 个答案:

答案 0 :(得分:1)

实际上python在..multiprocessing/forking.py模块上有一个bug,原因是:

  

当程序作为Windows服务运行时,但未打包   在单个可执行文件中,main_path将成为该路径   服务可执行文件(通常是pythonservice.exe)。当这个数据   使它成为子进程,prepare()函数将处理   main_path作为python模块的路径,并将尝试导入它。   这导致它失败。

你可以找到补丁here
或从here

下载整个文件