Skip to main content
 首页 » 编程设计

python之长时间运行进程的超时和 Windows 服务 (Python)

2025年05月04日7jillzhang

我有一个使用 python 创建的简单 Windows 服务。我的问题是我不知道服务需要多长时间才能完成,可能需要 15 秒,也可能需要 4 个多小时,具体取决于需要对数据执行的操作。 4 小时以上的情况很少见,但我遇到过这种情况。

下面是我一直遵循的 Windows 服务的一般模式。我去掉了所有的逻辑,但这不是问题,只留下了一个虚拟的日志命令。有没有办法在逻辑部分完成之前阻止服务继续或不刷新,而不是使用超时?

import win32service 
import win32serviceutil 
import win32api 
import win32con 
import win32event 
import win32evtlogutil 
import os 
import sys 
import time 
import logging 
class aservice(win32serviceutil.ServiceFramework): 
    _svc_name_ = "WeatherService" 
    _svc_display_name_ = "Weather Service" 
    _svc_description_ = "Downloads weather data from NOAA and creates maps" 
    def __init__(self, args): 
        win32serviceutil.ServiceFramework.__init__(self, args) 
        self.hWaitStop = win32event.CreateEvent(None, 0, 0, None)            
    def SvcStop(self): 
        self.ReportServiceStatus(win32service.SERVICE_STOP_PENDING) 
        win32event.SetEvent(self.hWaitStop)                       
    def SvcDoRun(self): 
        import servicemanager       
        servicemanager.LogMsg(servicemanager.EVENTLOG_INFORMATION_TYPE, 
                              servicemanager.PYS_SERVICE_STARTED,(self._svc_name_, ''))  
        self.timeout = 640000    #640 seconds / 10 minutes (value is in milliseconds) 
        #self.timeout = 120000     #120 seconds / 2 minutes 
        # This is how long the service will wait to run / refresh itself (see script below) 
        while 1: 
            # Wait for service stop signal, if I timeout, loop again 
            rc = win32event.WaitForSingleObject(self.hWaitStop, self.timeout) 
            # Check to see if self.hWaitStop happened 
            if rc == win32event.WAIT_OBJECT_0: 
                # Stop signal encountered 
                servicemanager.LogInfoMsg(self._svc_name_ + " - STOPPED!")  #For Event Log 
                break 
            else: 
                #[actual service code between rests] 
                try: 
                    logging.basicConfig(filename=r"c:\temp\example.log",level=logging.DEBUG, 
                                        format='%(asctime)s %(message)s') 
                    logging.debug('This message should go to the log file') 
                    logging.info('So should this') 
                    logging.warning('And this, too') 
 
                    #file_path = "C:\whereever\my_REAL_py_work_to_be_done.py" 
                    #execfile(file_path)             #Execute the script 
                    #inc_file_path2 = "C:\whereever\MORE_REAL_py_work_to_be_done.py" 
                    #execfile(inc_file_path2)        #Execute the script 
                except: 
                    pass 
                #[actual service code between rests] 
 
 
def ctrlHandler(ctrlType): 
    return True 
 
if __name__ == '__main__':    
    win32api.SetConsoleCtrlHandler(ctrlHandler, True)    
    win32serviceutil.HandleCommandLine(aservice) 

请您参考如下方法:

您可以启动一个新进程来处理长时间运行的事情。如果停止信号到达,您将终止子进程。