异常死亡进程的自动复活

原创 2001年12月09日 15:39:00

异常死亡进程的自动复活


一、问题的产生
我们或多或少都有这样的经历,在Windows上运行的应用程序常常会异常终止,需要通过手工重新将其启动起来。若计算机无人看守,异常终止的进程不能实时启动,则可能给生产造成损失。
本人在开发GPS全球卫星定位系统控制中心程序时,就遇到过控制中心程序异常终止死亡的情况,由此,找出了一个自动复活死亡进程的方法,供参考。
二、相关知识
通常,把一个应用程序的一次运行实例叫做一个进程,在一个进程内又可包含多条可并发执行的路径,每条执行路径叫做一个线程,一个进程至少包含一个主线程。主线程负责执行运行的启动代码。另外,一个进程可以创建若干子进程。当进程被创建时,系统自动产生主线程,主线程然后可创建更多的线程。
我们可以编写一个程序,让其创建、启动子进程,并监视进程的运行情况,在其出现异常终止时,立即重新创建并启动子进程即可。
三、相关函数  
1、创建一个子进程函数:
BOOL CreateProcess(
LPCTSTR lpApplicationName,
LPTSTR lpCommandLine,
LPSECURITY_ATTRIBUTES lpProcessAttributes,
LPSECURITY_ATTRIBUTES lpThreadAttributes,
BOOL bInheritHandles,  
DWORD dwCreationFlags,  
LPVOID lpEnvironment,  
LPCTSTR lpCurrentDirectory,
LPSTARTUPINFO lpStartupInfo,  
LPPROCESS_INFORMATION lpProcessInformation  
);
参数说明:
lpApplicationName:新进程将要使用的可执行文件的名字,必须包含扩展名。
LpCommandLine:新进程的命令行。若lpApplicationName为NULL,LpCommandLine 的第一个参数是新进程将要使用的可执行文件的名字,可以不包含扩展名,系统假定是exe文件。
LpProcessAttributes和lpThreadAttributes:分别是给进程对象和线程对象指定的安全属性。
BInheritHandles:指定该进程是否继承其父进程中的句柄。
dwCreationFlags:指定新进程产生方式的标志,可用逻辑操作符or相连接。
LpEnvironment:指向含有新进程将要使用的环境块字符串的一块内存,一般为NULL,使子进程继承父进程的一组环境块。
LpCurrentDirectory:设置子进程的当前驱动器和工作目录, 为NULL,子进程继承父进程的当前驱动器和工作目录。
LpStartupInfo:指向STARTUPINFO 的结构。一般让子进程使用缺省值。但要把该结构中的所有成员初始化为0,并设置cb为结构大小。
STARTUPINFO 结构如下:
typedef struct _STARTUPINFO {  
DWORD cb;  
LPTSTR lpReserved;  
LPTSTR lpDesktop;  
LPTSTR lpTitle;  
DWORD dwX;  
DWORD dwY;  
DWORD dwXSize;  
DWORD dwYSize;  
DWORD dwXCountChars;  
DWORD dwYCountChars;  
DWORD dwFillAttribute;  
DWORD dwFlags;  
WORD wShowWindow;  
WORD cbReserved2;  
LPBYTE lpReserved2;  
HANDLE hStdInput;  
HANDLE hStdOutput;  
HANDLE hStdError;  
} STARTUPINFO, *LPSTARTUPINFO;
lpProcessInformation 参数指向LPPROCESS_INFORMATION结构,CreateProcess在返回之前,填入有关子进程的信息,父进程正是利用该信息监测子进程是否终止。该结构如下:
typedef struct _PROCESS_INFORMATION {  
HANDLE hProcess;  
HANDLE hThread;  
DWORD dwProcessId;  
DWORD dwThreadId;  
} PROCESS_INFORMATION;  
hProcess和hThread分别是子进程的句柄和子进程的主线程的句柄,dwProcessId和dwThreadId分别是子进程的标识号和子进程的主线程的标识号。  
2、子进程终止检测函数
GetEXitCodeProcess(HANDLE hProcess, LPDWORD lpExitCode );
Hprocess:进程句柄,lpExitCode:进程终止时的退出码。
如果一个进程没有终止,lpExitCode 的返回值是STILL_ACTIVE,否则返回其他值。
四、方法的Delphi5语言实现
1、创建一个新的项目 Project1
选择File,New Application。在表单Form1上放一Memo组件,一个OK按钮组件,改变OK按钮组件的Cation属性为 CreateProcess。再放一个timer组件。设置timer组件的Interval值为1000,每秒检查一次进程是否终止。
2、在Unit1 Use节的Type后定义一个过程
procedure EstablishProcess;
在Unit1 Use节的Var后定义一个变量:
piProcInfoGPS:PROCESS_INFORMATION;
3、在Unit1 implementation节中编写EstablishProcess过程的实现代码如下:
procedure EstablishProcess;
Var
siStartupInfo:STARTUPINFO;
saProcess,saThread:SECURITY_ATTRIBUTES;
fSuccess:boolean;
begin
fSuccess:=false;
ZeroMemory(@siStartupInfo,sizeof(siStartupInfo));
siStartupInfo.cb:=sizeof(siStartupInfo);
saProcess.nLength:=sizeof(saProcess);
saProcess.lpSecurityDescriptor:=PChar(nil);
saProcess.bInheritHandle:=true;
saThread.nLength:=sizeof(saThread);
saThread.lpSecurityDescriptor:=PChar(nil);
saThread.bInheritHandle:=true;
fSuccess:=CreateProcess(PChar(nil),'c:/sr350/Sr350buff',@saProcess,@saThread,false,
CREATE_DEFAULT_ERROR_MODE,Pchar(nil),Pchar(nil),siStartupInfo,piProcInfoGPS);
if( not fSuccess)then
Form1.Memo1.Lines.Add('Create Process Sr350buff fail.')
else
Form1.Memo1.Lines.Add('Create Process Sr350buff success.')
end;
4、在CreateProcess按钮的OnClick事件中调用过程
EstablishProcess;
5、为Timer1的OnTimer事件编写代码:
Procedure TForm1.Timer1Timer(Sender: TObject);
Var
dwExitCode:DWORD;
fprocessExit:boolean;
Begin
  
dwExitCode:=0;
fprocessExit:=false;
fprocessExit:=GetExitCodeProcess(piProcInfoGPS.hProcess,dwExitCode);
if(fprocessExit and (dwExitCode<>STILL_ACTIVE))then
begin
Memo1.Lines.Add('SR350buff.exe进程终止');
CloseHandle(piProcInfoGPS.hThread);
CloseHandle(piProcInfoGPS.hProcess);
EstablishProcess;
end;
End;
6、程序中设可执行文件名为c:/sr350/sr350buff.exe,所以c:盘/sr350目录下需有sr350buff.exe文件。
7、编译联接,运行project1,单击CreateProcess可见c:/sr350/sr350buff.exe启动。关掉sr350buff.exe进程,可见sr350buff.exe自动再启动。

【UNET自学日志】Part11 玩家复活

上一部分玩家摧毁的方法是设置其enable为false,那么玩家的复活就是在玩家死后,显示复活的按钮,点击按钮后把相关的enable再次设置为true即可 新建脚本Player_Respawn ...
  • sinat_24994943
  • sinat_24994943
  • 2016年04月23日 21:06
  • 623

datanode启动之后很快有自己关闭掉

因为一直存在namenode重启无法正常启动,必须每次格式化namenode的情况,所以今天开始设置了core-site.xml中hadoop.tm.dir的设置。设置之后namenode终于摆脱了以...
  • yunlong34574
  • yunlong34574
  • 2014年03月16日 12:14
  • 7261

Tomcat 进程自动退出问题

最近在项目里遇到这样一个问题:应用部署在线下服务器上,线下服务器,相对来说配置低一些,同时可能和其它的服务部署在一起。后来遇到一个比较怪异的问题:应用跑一段时间,Tomcat进程就挂掉了。而且这个没有...
  • yiluoAK_47
  • yiluoAK_47
  • 2016年12月28日 10:14
  • 6708

Android应对进程被杀死--Service(五)-- 双进程Service常驻后台

最近项目用到Service常驻后台,研究了一下发现手Q和微信都是使用了双进程来保证一键清理后自动复活,copy网上双进程Service的例子,再结合onTrimMemory(),基本实现一键清理后自动...
  • f2006116
  • f2006116
  • 2016年03月20日 14:24
  • 1641

进程异常退出导致死锁的解决办法

最近碰到这么一个问题:程序先获得锁,然后进行一些操作,操作完成之后再把锁释放掉,然而在获得锁之后进行的一些操作中可能导致程序异常退出(比如段错误),可以看出还没有来得及把锁释放进程就蹦掉了,从而导致这...
  • wangzuxi
  • wangzuxi
  • 2015年03月31日 10:31
  • 2519

mongodb进程莫名退出

转载自:http://www.db2china.net/Article/34771 使用命令 ./mongod --dbpath=../data/db/ --logpath=../data/lo...
  • u014710520
  • u014710520
  • 2017年06月09日 14:10
  • 1113

linux下监视进程,若进程关闭则自动重启

从事嵌入式行业已经3年,说来惭愧,我目前除了电路系统设计,PCB设计,while(1)系统程序设计就基本上不会什么了。面对外面世界的巨大压力,我觉得提升自我已经是一件刻不容缓的事情,于是在上周开始,我...
  • funcye
  • funcye
  • 2013年04月28日 02:17
  • 585

android杀死进程

通常我们说缓存就是暂时把没在前台的程序放在内存里,比方说我打开短信应用,然后退回到Launcher打开微信,那么短信就成了所谓的后台程序放在了RAM里,这时候短信应用什么也不会干,就是像一个安静的美男...
  • u010852160
  • u010852160
  • 2016年07月13日 18:32
  • 218

linux下java程序异常关闭,自动启动做法

在linux下面运行java程序,一般情况下我们先打包成jar文件,然后放在linux下,用脚本去执行它。 一,打包java项目。一般用eclipse和netbeans直接把项目打包成jar就可以了,...
  • heli_lieren
  • heli_lieren
  • 2014年02月11日 10:55
  • 466

jvm学习笔记:第3章java判断对象是否死亡

3.2.2 根搜索算法 在主流的商用程序语言中(Java和C#,甚至包括前面提到的古老的Lisp),都是使用根搜索算法(GC Roots Tracing)判定对象是否存活的。这个算法的基本思路就...
  • sbvfhp
  • sbvfhp
  • 2015年02月01日 14:12
  • 1302
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:异常死亡进程的自动复活
举报原因:
原因补充:

(最多只允许输入30个字)