zoukankan      html  css  js  c++  java
  • linux创建进程和等待进程退出

             在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..
    ");
    
    	int nAppCount = sizeof(APP_INFO_Array)/sizeof(APP_INFO);
    	printf("Daemon: AppCount is [%d]
    ",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]
    ",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!
    ");
    			break;
    	    }
    		printf("Daemon: app [%d] returns
    ",ret_pid);
    		if(!WIFEXITED(status))
    		{
    			printf("Daemon: app [%d] terminated abnormally
    ",ret_pid);
    		}
    		else
    		{
    			printf("Daemon: app [%d] exited with code[%d]
    ",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]
    ",app_path,ret);
    		break;
    	default:
    		break;
    	}
    
    	return pid;
    }
    
  • 相关阅读:
    JavaScript循环 — for、for/in、while、do/while
    Git
    js根据日期获取所在周
    nodejs安装 Later version of Node.js is already installed. Setup will now exit 及 node与npm版本不符
    sqlserver 2014 json
    根据官方数据制作中国省市区数据库
    kubernetes系列③:集群升级-实践(参照官方文档)
    kubernetes系列:服务外部访问集中管理组件-ingress-nginx
    kubernetes系列-部署篇:Kubernetes的包管理工具-helm
    kubernetes系列-部署篇:使用kubeadm初始化一个高可用的Kubernetes集群
  • 原文地址:https://www.cnblogs.com/jiangu66/p/3231113.html
Copyright © 2011-2022 走看看