您的位置:首页 > 运维架构 > Linux

linux创建进程和等待进程退出

2013-08-01 20:08 453 查看
在WIN32下,在一个进程里我们可以使用CreateProcess()创建一个进程,然后通过调用WaitForSingleObect(), WaitForMultipleObject()等待进程退出。那么在linux下该如何实现呢?

以下的代码实现了一个daemon程序, daemon程序负责系统启动其它所有App,当其它应用出现异常退出的时候,daemon程序会重新启动它们。

/********************************************************************
filename:   daemon.c
created:    2013-07-17
author:     firehood
purpose:    daemon implement
*********************************************************************/
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <unistd.h>
#include <syslog.h>
#include <string.h>

typedef enum APP_ID_
{
APP_ID_MIN,
APP_ID_RTMP = APP_ID_MIN,
APP_ID_VIDTRANSFILT,
APP_ID_SOS,

//////////////////////
APP_ID_MAX,
}APP_ID;

typedef struct APP_INFO_
{
APP_ID  id;           // app id
const char* app_path; // app file path
const char* cmdline;  // app cmdline
int   start_interval; // waitting time before starting the app. (unit:ms)
}APP_INFO;

static APP_INFO APP_INFO_Array[] =
{
{APP_ID_RTMP,               "/opt/exe/crtmpserver/sbin/crtmpserver",  "/opt/exe/crtmpserver/etc/crtmpserver.lua"  ,0},
{APP_ID_VIDTRANSFILT,       "./VidTransFilt",                         NULL,                                        2000},
{APP_ID_SOS,                "/opt/exe/sos",                           NULL,                                        5000},
};

pid_t APP_pid[APP_ID_MAX];

int ExecuteApp(const char *app_path,const char *argv[]);
int GetAppIdByPid(pid_t pid);

int main(void)
{
/* Our process ID and Session ID */
pid_t pid, sid;

/* Fork off the parent process */
pid = fork();
if (pid < 0) {
exit(EXIT_FAILURE);
}
/* If we got a good PID, then
we can exit the parent process. */
if (pid > 0) {
exit(EXIT_SUCCESS);
}
#if 0
/* Change the file mode mask */
umask(0);

/* Open any logs here */

/* Create a new SID for the child process */
sid = setsid();
if (sid < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}

/* Change the current working directory */
if ((chdir("/")) < 0) {
/* Log the failure */
exit(EXIT_FAILURE);
}

/* Close out the standard file descriptors */
close(STDIN_FILENO);
close(STDOUT_FILENO);
close(STDERR_FILENO);
#endif

/* Daemon-specific initialization goes here */
printf("Daemon is running..\n");

int nAppCount = sizeof(APP_INFO_Array)/sizeof(APP_INFO);
printf("Daemon: AppCount is [%d]\n",nAppCount);

int i = 0;
for(i =0; i<nAppCount;i++)
{
usleep(APP_INFO_Array[i].start_interval*1000);
if(APP_INFO_Array[i].cmdline)
{
char* argv[3] ={0};
argv[0] = strrchr(APP_INFO_Array[i].app_path,'/')+1;
argv[1] = APP_INFO_Array[i].cmdline;
argv[2] = NULL;
APP_pid[APP_INFO_Array[i].id] = ExecuteApp(APP_INFO_Array[i].app_path,argv);
}
else
{
APP_pid[APP_INFO_Array[i].id] = ExecuteApp(APP_INFO_Array[i].app_path,NULL);
}
printf("Daemon: %s is running pid = [%d]\n",APP_INFO_Array[i].app_path,APP_pid[APP_INFO_Array[i].id]);
}

int status;
while(1)
{
pid_t ret_pid = wait(&status);
if(ret_pid == -1)
{
printf("Daemon: all app are exited!\n");
break;
}
printf("Daemon: app [%d] returns\n",ret_pid);
if(!WIFEXITED(status))
{
printf("Daemon: app [%d] terminated abnormally\n",ret_pid);
}
else
{
printf("Daemon: app [%d] exited with code[%d]\n",ret_pid,WEXITSTATUS(status));
}
int app_id = GetAppIdByPid(ret_pid);
if(app_id>=0 && app_id!=APP_ID_RTMP)
{
// restart the app
APP_pid[app_id] = ExecuteApp(APP_INFO_Array[app_id].app_path,APP_INFO_Array[app_id].cmdline);
}
}

exit(EXIT_SUCCESS);
}

int GetAppIdByPid(pid_t pid)
{
int i = 0;
for(i = 0; i<APP_ID_MAX;i++)
{
if(pid == APP_pid[i] & i != APP_ID_RTMP)
{
return i;
}
}
return -1;
}

int ExecuteApp(const char *app_path,const char *argv[])
{
if(app_path == NULL)
{
return 0;
}

pid_t pid = fork();

int ret;
switch(pid)
{
case -1:
perror("fork failed");
exit(-1);
case 0 :
ret = execv(app_path,argv);
printf("start app[%s] failed, ret= [%d]\n",app_path,ret);
break;
default:
break;
}

return pid;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: