进程自动重起

后台任务性质的程序无法确定的原因处于不可恢复状态时自动重新启动进程.
主要是应对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 pipe
		PIPE_ACCESS_INBOUND, // 1-way pipe -- send only
		PIPE_TYPE_BYTE, // send data as a byte stream
		1, // only allow 1 instance of this pipe
		0, // no outbound buffer
		0, // no inbound buffer
		0, // use default wait time
		NULL // use default security attributes
		);

	if (pipe == NULL || pipe == INVALID_HANDLE_VALUE) {
		return 1;
	}

	// This call blocks until a client process connects to the pipe
	BOOL result = ConnectNamedPipe(pipe, NULL);
	if (!result) {
		CloseHandle(pipe); // close the pipe
		return 1;
	}


	// The read operation will block until there is data to read
	char buffer[1024];
	DWORD numBytesRead = 0;
	result = ReadFile(
		pipe,
		buffer, // the data from the pipe will be put here
		1024 * sizeof(char), // number of bytes allocated
		&numBytesRead, // this will store number of bytes actually read
		NULL // not using overlapped IO
		);

	bool ret = false;
	if (result) {
		buffer[numBytesRead / sizeof(char)] = '\0'; // null terminate the string
		vector<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 access
			FILE_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 pipe
		data, // data to send
		strlen(data),
		&numBytesWritten, // will store actual amount of data sent
		NULL // 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/


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值