您的位置:首页 > 其它

进程的创建以及退出

2013-03-17 21:05 211 查看
在windows下创建子进程较常用到的API就是CreateProcess,可以通过以下的方式启动一个新进程:

STARTUPINFO si = {0};

PROCESS_INFORMATION pi = {0};

si.cb = sizeof(STARTUPINFO); //结构体大小

GetStartupInfo(&si); //初始化结构

si.wShowWindow = SW_HIDE; //新进程不显示窗口

si.dwFlags = STARTF_USESHOWWINDOW; //令si.wShowWindow生效

//关键步骤,CreateProcess函数参数意义请查阅MSDN

if (!CreateProcess( NULL, //可执行文件名,为NULL时,通过szCmdLine提供

szCmdLine, //命令行参数

NULL, //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。

//如果lpProcessAttributes参数为空(NULL),那么句柄不能被继承。

NULL, //指向一个SECURITY_ATTRIBUTES结构体,这个结构体决定是否返回的句柄可以被子进程继承。

//如果lpThreadAttributes参数为空(NULL),那么句柄不能被继承。

FALSE, //指示新进程是否从调用进程处继承了句柄

NULL, //指定附加的、用来控制优先类和进程的创建的标志

NULL, //指向一个新进程的环境块。如果此参数为空,新进程使用调用进程的环境

NULL, //子进程的工作路径,当进程名为相对路径时,必须填写

&si, //指向一个用于决定新进程的主窗体如何显示的STARTUPINFO结构体

&pi)) //指向一个用来接收新进程信息的PROCESS_INFORMATION结构体

{

return false;

}

WaitForSingleObject(pi.hProcess,INFINITE); //等待子进程结束

CloseHandle(pi.hThread); //关闭新进程的主线程

CloseHandle(pi.hProcess); //关闭新进程

在linux下创建子进程:

pid_t pid;

if(( pid = fork()) == -1 ) //创建子进程

{

exit(0); //创建进程失败,退出程序

} else if(pid == 0) { //子进程空间

char *args[]={FileMonitor, "-fp", lmonitorList[num].lm_strDirectory, NULL};

if(execve(FileMonitor, args, NULL)< 0) { //在子进程中调用FileMonitor进程

printf("execve ./wisFileMonitor -fp %s failed in the child process!/n", lmonitorList[num].lm_strDirectory);

CREATE_THREAD(StartMonitorThread, (THREAD_PARAM) num);

}

} else { //父进程空间

lmonitorList[num].lm_pid = pid;

lmonitorList[num].lm_bstop=false;

}

如果在创建子进程时,没有出现任何错误,fork函数将返回两次,一次在父进程中,另一次在子进程中。fork函数将新创建的子进程ID返回给父进程,并将0返回给子进程。

我们可以在程序中调用CreateProcess(),创建一个进程,该函数会创建一个进程内核对象以及一个线程内核对象,并且将 其计数设为1,在该函数成功返回前,会将子进程的进程内核对象以及线程内核对象句柄拷贝到结构体中,因此,该函数成功返回后,进程内核对象与线程内核对象的计数都变为2,则后面的操作中应该减少引用计数,以保证内核对象正常释放,否则会造成内存的泄露,减少计数的时机根据需要而定,减少计数后,应该避免再去引用该句柄(可能失效)。

当我们创建一个进程之后,可以有3种方法让该进程退出,

1. 调用ExitProcess,该函数的原型如下:

This function ends a process and all of its threads.

VOID ExitProcess
UINT uExitCode
);

Parameters

uExitCode [in] Specifies the exit code for the process and for all threads that are terminated as a result of this call.
To retrieve the process's exit value, use the
GetExitCodeProcess function.

To retrieve a thread's exit value, use the
GetExitCodeThread function.

Return Values

None.

2.调用函数TerminateProcess,该函数的原型如下:

This function terminates the specified process and all of its threads.

BOOL TerminateProcess(
HANDLE hProcess,
DWORD uExitCode
);

Parameters

hProcess [in] Handle to the process to terminate. uExitCode [in] Specifies the exit code for the process and for all threads terminated as a result of this call.
To retrieve the process's exit value, use the
GetExitCodeProcess function.

To retrieve a thread's exit value, use the
GetExitCodeThread function.

Return Values

Nonzero indicates success.

Zero indicates failure.

To get extended error information, call
GetLastError.

3.进程的所有线程都退出。

对于前面2种情况,区别在于进程的任何线程都可以ExitProcess终止本进程,而TerminateProcess则可以让进程的任何线程终止本进程或者其它的进程。前者让进程优雅的退出,而后者略带强制意味,其区别在于,前者会通知进程加载的其它模块,进程要退出了,而后者则不会通知,有可能会错过一些清理过程,虽然一般情况下,都会释放内存,清理堆栈,释放对象,但是我们在一般情况下还是使用前者较好,只有在万不得已的情况下才使用后者。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: