进程自动重起

来源:互联网 发布:young网络用户名 编辑:程序博客网 时间:2024/05/16 19:40
后台任务性质的程序无法确定的原因处于不可恢复状态时自动重新启动进程.
主要是应对Berkeley DB DB_RUNRECOVERY错误特例的情况.

处理步骤:
程序更新:
.更新bbox.dll
.把restart_proc.exe复制到服务器主目录下
    
配置修改:    
bbox.conf增加以下配置项:
<debug_flag>1</debug_flag> <!--用于诊断的配置项,bit0-回路时是否重新启动 -->    

服务器程序在判定不可恢复时,启动restart_proc程序,由它立即重新启动服务程序。

restart_proc代码:
///< 启动时创建管道,启动者通过管道与本进程通信,发送需要启动的进程ID///< 本进程根据进程ID,确定执行程序.///< 关闭进程///< 重新启动进程int _tmain(int argc, _TCHAR* argv[]) {HANDLE pipe = CreateNamedPipe("\\\\.\\pipe\\restart_proc_pipe", // name of the pipePIPE_ACCESS_INBOUND, // 1-way pipe -- send onlyPIPE_TYPE_BYTE, // send data as a byte stream1, // only allow 1 instance of this pipe0, // no outbound buffer0, // no inbound buffer0, // use default wait timeNULL // use default security attributes);if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {return 1;}// This call blocks until a client process connects to the pipeBOOL result = ConnectNamedPipe(pipe, NULL);if (!result) {CloseHandle(pipe); // close the pipereturn 1;}// The read operation will block until there is data to readchar buffer[1024];DWORD numBytesRead = 0;result = ReadFile(pipe,buffer, // the data from the pipe will be put here1024 * sizeof(char), // number of bytes allocated&numBytesRead, // this will store number of bytes actually readNULL // not using overlapped IO);bool ret = false;if (result) {buffer[numBytesRead / sizeof(char)] = '\0'; // null terminate the stringvector<string> vs;SplitString(buffer,vs,',');DWORD pid = atoi(vs[0].c_str());string cmd_para = vs[1];HANDLE hModuleSnap = NULL; MODULEENTRY32 me32 = {0}; hModuleSnap = CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, pid); if (hModuleSnap == INVALID_HANDLE_VALUE) return -1;me32.dwSize = sizeof(MODULEENTRY32); bool bFound= false;if (Module32First(hModuleSnap, &me32)) { do { if (me32.th32ProcessID == pid) { bFound = TRUE; } } while (!bFound && Module32Next(hModuleSnap, &me32)); } CloseHandle (hModuleSnap);  if (!bFound)return -1;string cmd = string(me32.szExePath)+string(" ")+ cmd_para;HANDLE handle =  OpenProcess(PROCESS_ALL_ACCESS, FALSE, pid);while(1) {DWORD exit_code = 0;if (!GetExitCodeProcess(handle,&exit_code))break;if (exit_code!=STILL_ACTIVE)break;ret = TerminateProcess(handle,0);}ExecuteCmd(cmd.c_str(),true,false,0);} CloseHandle(pipe);return 0;}


调用代码:

/////////////////////////////////////////////////////////////////int ExecuteCmd(const char *cmdStr,bool show_window,bool wait_fin,HANDLE *handle){STARTUPINFO si;PROCESS_INFORMATION pi;GetStartupInfo(&si);si.cb = sizeof(STARTUPINFO);si.hStdError = GetStdHandle(STD_ERROR_HANDLE);si.hStdOutput = GetStdHandle(STD_OUTPUT_HANDLE);si.hStdInput = GetStdHandle(STD_INPUT_HANDLE);si.dwFlags = STARTF_USESTDHANDLES;if (!show_window) {si.wShowWindow = SW_HIDE;si.dwFlags |= STARTF_USESHOWWINDOW;}ZeroMemory( &pi, sizeof(pi) );if (!CreateProcess(NULL,const_cast<char*>(cmdStr) ,NULL,NULL,FALSE,NULL,NULL,NULL,&si,&pi)) {DWORD ErrorCode = GetLastError();return -1;}DWORD result = 0;if (wait_fin) {WaitForSingleObject( pi.hProcess, INFINITE );GetExitCodeProcess(pi.hProcess,&result);}if (handle) {*handle = pi.hProcess;}return result;}int restart() {HANDLE handle = 0;if (ExecuteCmd("restart_proc",true,false,&handle))return -1;HANDLE pipe = INVALID_HANDLE_VALUE;while(pipe == INVALID_HANDLE_VALUE) {pipe = CreateFile("\\\\.\\pipe\\restart_proc_pipe",GENERIC_WRITE, // only need read accessFILE_SHARE_READ | FILE_SHARE_WRITE,NULL,OPEN_EXISTING,FILE_ATTRIBUTE_NORMAL,NULL);Sleep(1000);}DWORD dwPID = GetCurrentProcessId();char data[32];sprintf(data,"%lu,-d",dwPID);DWORD numBytesWritten = 0;int result = WriteFile(pipe, // handle to our outbound pipedata, // data to sendstrlen(data),&numBytesWritten, // will store actual amount of data sentNULL // not using overlapped IO);CloseHandle(pipe);WaitForSingleObject( handle, INFINITE );return 0;}

bbox调用(CBBoxPlugin::HandleInput_i函数中)

if (IsIncomingMsg(pwm)) { ///< 来自外部的消息,如果是非本地机构,则表示非预期的消息if ((tt==1&&!IsLocalOrg(tid))||(tt == 2 && !IsLocalOrg(ORGID_IN_USERSERIAL(tid)))) {nlogger_->log(LO_STDOUT|LO_FILE,SEVERITY_ERROR,"CBBoxPlugin::HandleInput_i来自外部的非本地消息 \n");if (debug_flag_&1) {restart(); ///< 重新启动进程return -1;}}}

实现参考资料:

Introduction to Win32 Named Pipes (C++)
http://www.avid-insight.co.uk/2012/03/introduction-to-win32-named-pipes-cpp/


原创粉丝点击