我使用的是python2.5.2或2.7,这是一个HTTP服务器(BaseHTTPServer),可以启动各种任务。其中一个进程是长时间运行的进程。我希望能够做的是启动这个进程,然后关闭我的HTTP服务器并重新启动。在
问题是我的服务器关闭(关闭所有线程和python.exe进程退出Windows显示的活动任务列表,启动的进程仍在运行,但是netstat-ab显示系统进程有我的端口,HTTP服务器在监听状态下监听,并且与进程ID相关联,这个进程ID曾经是我的HTTP服务器。在启动的进程完成之前,该端口一直保持打开状态,这使得无法重新启动我的HTTP服务器。在
无论我终止python进程,还是CTRL-C窗口,都会显示相同的行为。我读了大量的文档,每个人都建议使用子流程.Popen,但即使使用它,似乎也会将主进程的一部分与已启动的进程相关联。在
我将按如下方式启动该实用程序:
try:
# NOTE: subprocess.Popen is hanging up the 8091 port until the utility finishes.
# This needs to be addressed, otherwise, I'll never be able to restart the
# client when the utility has been launched.
listParams = [ 'C:/MyPath/My.exe', '-f', os.path.join ( sXMLDir, sXmlFile ) ]
proc = subprocess.Popen ( listParams, cwd='C:/MyPath', creationflags=0x00000008 )
iSts = 200
sStatus = 'Utility was successfully launched.'
except:
iSts = CMClasses.HTTPSTS_STARTSLEDGE_SYSTEM
sStatus = 'An exception occurred launching utility: ' + str ( sys.exc_type ) + ":" + str ( sys.exc_value ) + '.'
我的HTTP服务器实现如下,它允许我的主程序处理CTRL-C:
^{pr2}$下面是netstat-ab(我的python进程是3728,端口是8091)在启动实用程序之前的结果:
活动连接
协议本地地址外部地址状态PID
TCP vtxshm-po-0101:8091 vtxshm-po-0101:0监听3728 [python.exe]在
TCP vtxshm-po-0101:8091 vtxshm-po-0101:23193时间_WAIT 0 [框架服务.exe]在
下面是netstat-ab在启动实用程序后,在点击Control-C并停止python之后的结果。(请注意,操作系统认为该端口仍处于侦听状态,分配给PID 3728,但该进程已不存在于任务管理器中,它现在由系统拥有,并以某种方式与snmp.exe(我们甚至不用)。这些连接被理解为来自另一个服务器以启动实用程序的请求。在
活动连接
协议本地地址外部地址状态PID
TCP vtxshm-po-0101:8091 vtxshm-po-0101:0监听3728 [系统]
TCP vtxshm-po-0101:8091 CH2ChaosMon公司密钥服务器:2133 TIME_WAIT0 TCP vtxshm-po-0101:8091 CH2ChaosMon公司密钥服务器:2134 TIME_WAIT0 TCP vtxshm-po-0101:8091 vtxshm-po-0101:23223时间_WAIT 0 [snmp.exe]在
是否有人成功地从python启动了一个进程,并且完全独立于启动过程运行?如果是的话,你能告诉我这个秘密吗?在
所以你可以定义:
在这里,实例中不保留对变量
^{pr2}$server
的引用。这是一个问题,因为它意味着不可能更改下面类中的self.stop
标志:当您执行
server_forever
方法时,它会阻塞它的线程。由于没有保留对其父实例的引用,因此无法设置self.stop = True
。实际上,在代码中没有尝试这样做,所以套接字很可能挂起。如果handle_request
正在阻塞(如果不设置超时,这也是一个问题)。在您应该注意到
serve_forever
的默认实现可以用server.shutdown
停止,因此检查self.stop
标志的状态是多余的。在我建议将您的
LaunchHTTPServer
类更新为如下内容:通过上面的设置,您现在可以从键盘捕捉Ctrl-C中断,并确保调用实例的
stop
方法来干净地关闭套接字并退出。在我要回答一个稍微不同的问题,因为这是我能找到的最接近的类似问题。在
我遇到了一个程序的问题,该程序监听端口并使用子流程.Popen(). 如果我正在执行的脚本在后台运行一个长时间运行的作业(通过),并且我终止了主程序,则长时间运行的作业将接管主程序的侦听端口。在
主程序:
当httpd服务器接收到一个请求时,它将运行“start”long_工艺sh'. 脚本如下所示:
^{pr2}$开始\u long_工艺sh立即返回,请求服务完成。现在问题来了:
如果我在
sleep
仍在运行时终止web服务器,sleep
将接管侦听端口:解决方案是在调用脚本时关闭除0、1和2(stdin、stdout、stderr)以外的所有文件描述符。Popen()为此提供了一个标志“close_fds”:
现在睡眠不再束缚监听端口:
$netstat-pant | grep 0.0.0.0:8000 美元
发生这种情况的原因是子进程从其父进程继承打开文件描述符。让我恼火的是它包括监听端口。我以前见过“close”选项,但认为它也关闭了STDIN、STDOUT和STDERR。但它没有,所以您仍然可以像正常一样与子进程通信。在
相关问题 更多 >
编程相关推荐