精华内容
下载资源
问答
  • 我们可以写一个创造守护进程的函数,在程序运行时调用这个函数从而把这个程序变成一个守护进程。 这个函数需要有以下几个步骤: 子进程等待父进程退出 子进程使用setsid创建新的会话期,脱离控制台 调用chdir将当前...

    我们可以写一个创造守护进程的函数,在程序运行时调用这个函数从而把这个程序变成一个守护进程。
    这个函数需要有以下几个步骤:

    1. 子进程等待父进程退出
    2. 子进程使用setsid创建新的会话期,脱离控制台
    3. 调用chdir将当前工作目录设置为/
    4. umask设置为0以取消任何文件权限屏蔽
    5. 关闭所有文件描述符 用sysconf来获取最大的文件描述符个数
    6. 将0、1、2定位到/dev/null
      下面就是一个创建守护进程的函数了。
    void create_daemon(void)
    {
    	pid_t pid = 0;
    	
    	pid = fork();
    	if (pid < 0)
    	{
    		perror("fork");
    		exit(-1);
    	}
    	if (pid > 0)
    	{
    		exit(0);
    	}
    	//setsid将当前进程设置成一个新的会话期session,目的为了让当前进程脱离控制台
    	pid = setsid();
    	if (pid < 0)
    	{
    		perror("setsid");
    		exit(-1);
    	}
    	//将当前工作目录设置为根目录
    	chdir("/");
    	//umask设置为0确保将来进程有最大的文件操作权限
    	umask(0);
    	//关闭所有文件描述符
    	//先要获取当前系统中所允许打开的最大的文件描述符的数目
    	int i = 0;
    	int cnt = sysconf(_SC_OPEN_MAX);
    	for (i = 0; i < cnt; i++)
    	{
    		close(i);
    	}
    	open("/dev/null", O_RDWR);
    	open("/dev/null", O_RDWR);
    	open("/dev/null", O_RDWR);
    }
    

    --------------------------本文内容借鉴朱有鹏老师的课程内容-------------------------

    展开全文
  • 总结如何创建个守护进程

    千次阅读 2016-07-27 20:58:50
    所以要想创建个守护进程,就要实现满足这两点。 在此之前,要先介绍一下进程组和会话组。 一个进程组可以包含多个进程 进程组中的这些进程之间不是孤立的,他们彼此之间或者存在者父子、兄弟关系,...

    守护进程是指在后台运行的,没有控制终端与之相连的进程。它独立于控制终端,经常周期性地执行某种任务。

    所以要想创建一个守护进程,就要实现满足这两点。

    在此之前,要先介绍一下进程组和会话组。


    一个进程组可以包含多个进程

    进程组中的这些进程之间不是孤立的,他们彼此之间或者存在者父子、兄弟关系,或者在功能有相近的联系。

    那linux为什么要有进程组呢?其实提供进程组就是方便管理这些进程。假设要完成一个任务,需要同时并发100个进程,当用户由于某种原因要终止这个任务时,要是没有进程组,就需要一个个去杀死这些进程,设置了进程组后,就可以对进程组中的进程进行每个杀死。


    进程

    --------------------------------------------- 

    每个进程必定属于一个进程组,也只能属于一个进程组。

    子进程属于父进程所在的进程组。  

    一个进程除了有进程ID外,还有一个进程组ID,每个进程组也有唯一的进程组ID。

    每个进程组有一个进程组组长,进程组组长的进程ID和组ID相同


    会话    
    --------------------------------------------- 
        会话期则是一个或多个进程组的集合。当一个用户登陆一次终端时就会产生一个会话,每个会话有一个会话首进程,即创建会话的进程,建立与终端连接的就是这个会话首进程,也被称为控制进程。通常情况下,用户登录后所执行的所有程序都属于一个会话期,而其登录shell则是会话期首进程,并且它所使用的终端就是会话期的控制终端。当我们退出登录(logout)时,所有属于这个会话期的进程都将被终止。 
        (1). 一次登录形成一个会话 
        (2). 一个会话可包含多个进程组, 但只能有一个前台进程组. 
        (3). setsid()可建立一个新的会话;如果调用该函数的进程不是进程组的领头进程, 该函数才能建立新的会话. 
    调用setsid()之后, 调用进程将成为新会话的领头进程. 
     
    控制终端 
    --------------------------------------------- 
        (1) 会话的领头进程打开一个终端之后, 该终端就成为该会话的控制终端 (SVR4/Linux) 
        (2) 与控制终端建立连接的会话领头进程称为控制进程 (session leader) 
        (3) 一个会话只能有一个控制终端 
        (4) 产生在控制终端上的输入和信号将发送给会话的前台进程组中的所有进程 
        (5) 终端上的连接断开时(比如网络断开或Modem断开), 挂起信号将发送到控制进程(session leader)



    怎样编写守护进程:

    1. 在后台运行。 
       调用fork产生一个子进程,然后释放掉父进程,也就是说创建一个孤儿进程,此时子进程已经成为后台进程。
        if(pid=fork()) 
        exit(0);//是父进程,结束父进程,子进程继续 
    这么做不仅实现了让进程后台运行,同事保证了子进程是父进程创建的,属于父进程所在进程组,所以保证了子进程一定不是进程组组长,为了下一步脱离终端提供保证。
    2. 脱离控制终端,登录会话和进程组 
        
       控制终端,登录会话和进程组通常是从父进程继承下来的。我们的目的就是要摆脱它们,使之不受它们的影响。方法是在第1点的基础上,调用setsid()使进程成为会话组长:


    调用setsid有下面的3个作用:
    (1)让进程摆脱原会话的控制
    (2)让进程摆脱原进程组的控制
    (3)让进程摆脱原控制终端的控制
     也就是说由于创建守护进程的第一步调用了fork函数来创建子进程,再将父进程退出。由于在调用了fork函数时,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变,因此,这还不是真正意义上的独立开来,而setsid函数能够使进程完全独立出来,从而摆脱其他进程的控制。

    说明:当进程是会话组长时setsid()调用失败。但第一点已经保证进程不是会话组长。setsid()调用成功后,进程成为新的会话组长和新的进程组长,并与原来的登录会话和进程组脱离。由于会话过程对控制终端的独占性,进程同时与控制终端脱离。 


    3. 禁止进程重新打开控制终端 
         现在,进程已经成为无终端的会话组长。但它可以重新申请打开一个控制终端。可以通过使进程不再成为会话组长来禁止进程重新打开控制终端: 
        if(pid=fork()) 
        exit(0);//结束第一子进程,第二子进程继续(第二子进程不再是会话组长) 
    为什么要创建两次进程呢? 这是因为第二步结束后,进程创建了一个新的会话组,并成为会话组长,而会话组长可能获得控制终端,如果获得了控制终端那么或这个进程就不是守护进程了。所以添加了这几句代码,让进程失去会话组长的身份,从而没有获得控制终端的权限。
    4. 关闭打开的文件描述符 
    同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。
    在上面的第二步之后,守护进程已经与所属的控制终端失去了联系。因此从终端输入的字符不可能达到守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。通常按如下方式关闭文件描述符:
    for(i=0;i<MAXFILE;i++)
    close(i);
    5. 改变当前工作目录 
        这一步也是必要的步骤。使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如“/mnt/usb”)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让"/"作为守护进程的当前工作目录,这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数式chdir。
    6. 重设文件创建掩模 
      进程从创建它的父进程那里继承了文件创建掩模。它可能修改守护进程所创建的文件的存取位。为防止这一点,将文件创建掩模清除:umask(0); 
    7. 处理SIGCHLD信号 
       处理SIGCHLD信号并不是必须的。但对于某些进程,特别是服务器进程往往在请求到来时生成子进程处理请求。如果父进程不等待子进程结束,子进程将成为僵尸进程(zombie)从而占用系统资源。如果父进程等待子进程结束,将增加父进程的负担,影响服务器进程的并发性能。在Linux下可以简单地将SIGCHLD信号的操作设为SIG_IGN。 
    signal(SIGCHLD,SIG_IGN); 这样,内核在子进程结束时不会产生僵尸进程。




    这样,一个简单的守护进程就建立起来了。


    展开全文
  • 何为守护进程 、进程组 / 组长进程 / 会话 / 会话首进程 、守护进程创建步骤 、创建守护进程程序示例

    何为守护进程

    守护进程(daemon)是一类在后台运行的特殊进程,其生存期较长独立于控制终端、执行特定的系统任务。很多守护进程在系统引导的时候启动,并且一直运行直到系统关闭。另一些只在需要的时候才启动,完成任务后就自动结束。

    我们先来学习几个新概念:会话、会话首进程、进程组、组长进程。


    进程组 / 组长进程 / 会话 / 会话首进程

    进程组

    进程组:每个进程都属于一个进程组,进程组中可以包含一个或多个进程。进程组中有一个组长进程(第一个进程),组长的进程 ID 是进程组 ID(PGID)。

    • 当父进程,创建子进程的时候,默认子进程与父进程属于同一进程组

    • 组长进程可以创建一个进程组,创建该进程组中的进程,然后终止。只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关

    • 进程组生存期:进程组创建到最后一个进程离开(终止或转移到另一个进程组)。


    操作函数:

    1、getpgrp函数:获取当前进程的进程组ID

    pid_t getpgrp(void);  // 总是返回调用者的进程组ID
    

    2、getpgid函数:获取指定进程的进程组ID

    pid_t getpgid(pid_t pid);  // 成功:0;失败:-1,设置errno
    

    如果pid = 0,那么该函数作用和getpgrp一样。

    3、setpgid函数:改变进程默认所属的进程组。通常可用来加入一个现有的进程组或创建一个新进程组。

    /*
    ** 将参数1对应的进程,加入参数2对应的进程组中。
    ** 成功:0;失败:-1,设置errno
    **/
    int setpgid(pid_t pid, pid_t pgid); 
    

    注意:

    • 改变子进程为新的组,应在fork后,在exec前
    • 权级问题。非root进程只能改变自己创建的子进程,或有权限操作的进程。

    会话

    会话:多个进程组构成一个会话建立会话的进程是会话的领导进程,即会话首进程,该进程 ID 为会话的 SID。

    会话中的每个进程组称为一个作业。会话可以有一个进程组称为会话的前台作业,其它进程组为后台作业。

    一个会话可以有一个控制终端,当控制终端有输入和输出时都会传递给前台进程组,比如Ctrl + Z。会话的意义在于能将多个作业通过一个终端控制,一个前台操作,其它后台运行


    创建会话的注意事项:

    • 调用进程不能是进程组组长,该进程变成新会话首进程(session header)
    • 该进程成为一个新进程组的组长进程
    • 需有root权限(ubuntu不需要)
    • 新会话丢弃原有的控制终端,该会话没有控制终端
    • 若调用进程是组长进程,则出错返回
    • 建立新会话时,先调用fork,父进程终止,子进程调用setsid

    操作函数:
    1、getsid函数:获取进程所属的会话ID

    //成功:返回调用进程的会话ID;失败:-1,设置errno
    pid_t getsid(pid_t pid); 
    

    pid为0表示查看当前进程session ID


    如果调用进程非组长进程,那么就能创建一个新会话

    • 该进程变成新会话的首进程
    • 该进程成为一个新进程组的组长进程
    • 该进程没有控制终端,如果之前有,则会被中断(会话过程对控制终端的独占性)

    也就是说:组长进程不能成为新会话首进程,新会话首进程必定成为组长进程


    ps ajx命令查看系统中的进程。参数a表示不仅列当前用户的进程,也列出所有其他用户的进程,参数x表示不仅列有控制终端的进程,也列出所有无控制终端的进程,参数j表示列出与作业控制相关的信息
    在这里插入图片描述
    2、setsid函数:创建一个会话,并以自己的ID设置进程组ID,同时也是新会话的ID。

    pid_t setsid(void); //成功:返回调用进程的会话ID;失败:-1,设置errno
    

    调用了setsid函数的进程,既是新会话首进程,也是新的组长进程。



    简单总结如下:

    进程组和会话在进程之间形成了两级的层次:进程组是一组相关进程的集合,会话是一组相关进程组的集合。
    图示aopscjasj


    程序示例

    我们接下来通过上面介绍的函数来查看一下一个进程及其子进程的相关信息

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main()
    {
        printf("pid = %d, ppid = %d, pgid = %d, sid = %d \n",
         getpid(), getppid(), getpgrp(), getsid(0));
    }
    

    程序运行结果如下:

    我们可以看到,当启动一个新进程时,是由其父进程(终端bash)创建,并且该新进程所属的会话ID就是bash的PID因为它属于当前bash的创建的会话,那么bash为该会话的会话首进程

    另外我们看到,新进程的pgid即它的进程组ID就为它自身的pid,即当只启动一个进程时,进程组只有一个成员,就是它自身,因此该新进程也是新创建进程组的进程组长

    那么接下来我们在程序中fork()一个子进程,看一下结果:

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main()
    {
        fork();
        printf("pid = %d, ppid = %d, pgid = %d, sid = %d \n",
         getpid(), getppid(), getpgrp(), getsid(0));
    }
    

    我们可以看到,子进程的ppid就是创建它的父进程的id,子进程所属的进程组id就为组长进程的pid,即它父进程的pid。它们的sid都为当前终端的pid

    那么还有一种情况如下图所示:

    我们可以看到子进程的ppid为1,即说明了父进程已结束退出,那么有pid为1的init进程接管,但是我们看到其进程组id仍为其父进程(进程组组长)的pid,这也说明了我们前面所讲的:
    只要进程组中有一个进程存在,进程组就存在,与组长进程是否终止无关


    守护进程的创建步骤

    1、fork()创建子进程,父进程exit()退出

    进程 fork 后,父进程退出。这么做的原因有以下两点:

    • 如果守护进程是通过 Shell 启动,父进程退出,Shell 就会认为任务执行完毕,之后的所有工作都在子进程中完成,而用户在Shell终端里则可以执行其他命令,从而在形式上做到了与控制终端的脱离,在后台工作。这时子进程由 init 收养
    • 子进程继承父进程的进程组 ID,保证了子进程不是进程组组长,因为下面将调用setsid(),它要求必须不是进程组长。

    2、在子进程调用setsid()创建新会话

    在调用了 fork() 函数后,子进程全盘拷贝了父进程的会话期、进程组、控制终端等,虽然父进程退出了,但会话期、进程组、控制终端等并没有改变。这还不是真正意义上的独立开来,而 setsid()函数,使子进程完全独立出来,脱离控制。

    setsid()创建一个新会话,调用进程担任新会话的首进程,其作用有:

    • 使当前进程脱离原会话的控制
    • 使当前进程脱离原进程组的控制
    • 使当前进程脱离原控制终端的控制

    这样,当前进程才能实现真正意义上完全独立出来,摆脱其他进程的控制


    3、再次 fork() 一个子进程,父进程exit()退出

    现在,进程已经成为无终端的会话组长(会话首进程),但它可以重新申请打开一个控制终端,可以通过 fork() 一个子进程,该子进程不是会话首进程,该进程将不能重新打开控制终端。退出父进程。

    也就是说通过再次创建子进程结束当前进程,使进程不再是会话首进程来禁止进程重新打开控制终端。


    4、在子进程中调用chdir()让根目录“/”成为子进程的工作目录

    这一步也是必要的步骤。使用fork创建的子进程继承了父进程的当前工作目录。由于在进程运行中,当前目录所在的文件系统(如“/mnt/dev”)是不能卸载的,这对以后的使用会造成诸多的麻烦(比如系统由于某种原因要进入单用户模式)。因此,通常的做法是让"/"作为守护进程的当前工作目录这样就可以避免上述的问题,当然,如有特殊需要,也可以把当前工作目录换成其他的路径,如/tmp。改变工作目录的常见函数是chdir。(避免原父进程当前目录带来的一些麻烦)


    5、在子进程中调用umask()重设文件权限掩码为0

    文件权限掩码是指屏蔽掉文件权限中的对应位。比如,有个文件权限掩码是050,它就屏蔽了文件组拥有者的可读与可执行权限(就是说可读可执行权限均变为7)。

    由于使用fork函数新建的子进程继承了父进程的文件权限掩码,这就给该子进程使用文件带来了诸多的麻烦。因此把文件权限掩码重设为0即清除掩码(权限为777),这样可以大大增强该守护进程的灵活性。通常的使用方法为umask(0)。(相当于把权限开发)


    6、在子进程中close()不需要的文件描述符

    同文件权限码一样,用fork函数新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读写,但它们一样消耗系统资源,而且可能导致所在的文件系统无法卸下。其实在上面的第二步之后,守护进程已经与所属的控制终端失去了联系

    因此从终端输入的字符不可能到达守护进程,守护进程中用常规方法(如printf)输出的字符也不可能在终端上显示出来。所以,文件描述符为0、1和2 的3个文件(常说的输入、输出和报错)已经失去了存在的价值,也应被关闭。(关闭失去价值的输入、输出、报错等对应的文件描述符)

    for (i=0; i < MAXFILE; i++)
    	close(i); // 全部关闭
    

    7、守护进程退出处理

    当用户需要外部停止守护进程运行时,往往会使用 kill 命令停止该守护进程所以,守护进程中需要编码来实现 kill 发出的signal信号处理,达到进程的正常退出

    创建守护进程程序示例

    #include <stdio.h>
    #include <assert.h>
    #include <stdlib.h>
    #include <unistd.h>
    #include <time.h>
    #include <sys/stat.h>
    
    int main()
    {
    	/* 1、创建子进程,父进程退出 */
    	if (fork() != 0)
    	{
    		exit(0);
    	}
    
    	/* 2、setsid()创建会话 */
    	setsid();
    	
    	/* 3、再次fork,父进程退出,即使新进程不再是会话首进程 */
    	if (fork() != 0)
    	{
    		exit(0);
    	}
    	
    	/* 4、让根目录成为子进程的工作目录 */
    	chdir("/");
    
    	/* 5、清空掩码,大大增强该守护进程的灵活性 */
    	umask(0);
    
    	/* 6、清空所有文件描述符,让其不占用系统资源 */
    	int maxfd = getdtablesize();
    	int i = 0;
    	for (; i < maxfd; ++i)
    	{
    		close(i);
    	}
    
    	/* 每隔5s将当前时间写入日志文件 */
    	while (1)
    	{
    		FILE* fp = fopen("/home/zy/Learn/a.log", "a+");
    		if (fp == NULL)
    		{
    			break;
    		}
    
    		time_t tv;
    		time(&tv);
    		fprintf(fp, "Time is %s", asctime(localtime(&tv)));
    		fclose(fp);
    		sleep(5);
    	}
    
    	exit(0);
    }
    

    运行上述程序,在终端中不会有任何输出,因为它已经变为了守护进程长期在系统中存在,但我们可以通过ps -ef命令查看到。
    在这里插入图片描述
    那么我们打开 a.log 日志文件,通过tail -f命令值实时刷新显示末尾数据。
    我们可以看到,每隔5s文件中就多了一行时间信息。证明我们所创建的守护进程一直在后台工作。

    我们可以通过kill命令结束守护进程。
    在这里插入图片描述

    展开全文
  • 创建守护进程

    2017-07-04 09:49:48
    守护进程是一在后台运行并且不受任何终端控制的进程,也称精灵进程(Daemon),它独⽴立于控制终端并且周期性地执⾏行某种任务或等待处理某些发⽣生的事件。守护进程是⼀一种很有用的进程。Linux的大多数服务器...
                                                                          守护进程
    守护进程是一个在后台运行并且不受任何终端控制的进程,也称精灵进程(Daemon),它独⽴立于控制终端并且周期性地执⾏行某种任务或等待处理某些发⽣生的事件。守护进程是⼀一种很有用的进程。Linux的大多数服务器就是⽤守护进程实现的。⽐如,Internet服务器inetdWeb服务器httpd等。同时,守护进程完成许多系统任务。⽐如,作业规划进程crondLinux系统启动时会启动很多系统服务进程,这些系统服务进程没有控制终端,不能直接和用户交互。其它进程都是在用户登录或运行程序时创建,在运行结束或用户注销时终止,但系统服务进程不受用户登录注销的影响,它们一直在运⾏行着。这种进程有⼀一个名称叫守护进程(Daemon)
    Unix操作系统有很多典型的守护进程(其数目根据需要或20—50不等),它们在后台运行,执行不同的管理任务。
    用户使守护进程独立于所有终端是因为,在守护进程从一个终端启动的情况下,这同一个终端可能被其他的用户使用。例如,用户从一个终端启动守护进程后退出,然后另外一个人也登录到这个终端。用户不希望后者在使用该终端的过程中,接收到守护进程的任何错误信息。同样,由终端键人的任何信号(例如中断信号)也不应该影响先前在该终端启动的任何守护进程的运行。虽然让服务器后台运行很容易(只要shell命令行以&结尾即可),但用户还应该做些工作,让程序本身能够自动进入后台,且不依赖于任何终端。
    守护进程没有控制终端,因此当某些情况发生时,不管是一般的报告性信息,还是需由管理员处理的紧急信息,都需要以某种方式输出。Syslog 函数就是输出这些信息的标准方法,它把信息发送给 syslogd 守护进程。
    创建守护进程步骤:
    (1)重设文件创建掩码
    文件创建掩码是指屏蔽掉文件创建时的对应位。由于使用fork函数新建的子进程继承了父进程的文件创建掩码,这就给该子进程使用文件带来了诸多的麻烦。因此,把文件创建掩码设置为0,可以大大增强该守护进程的灵活性。设置文件创建掩码的函数是umask,通常的使用方法为umask(0)。
    (2)创建子进程,终止父进程
    由于守护进程是脱离控制终端的,因此首先创建子进程,终止父进程,使得程序在shell终端里造成一个已经运行完毕的假象。之后所有的工作都在子进程中完成,而用户在shell终端里则可以执行其他的命令,从而使得程序以僵尸进程形式运行,在形式上做到了与控制终端的脱离。
    (3)在子进程中创建新会话
    这个步骤在这里使用的是系统函数setsid。setsid函数用于创建一个新的会话,并担任该会话组的组长。调用setsid仃三个作用:让进程摆脱原会话的控制、让进程摆脱原进程组的控制和让进程摆脱原控制终端的控制。在调用fork函数时,子进程全盘拷贝父进程的会话期(session,是一个或多个进程组的集合)、进程组、控制终端等,虽然父进程退出了,但原先的会话期、进程组、控制终端等并没有改变,因此,那还不是真正意义上使两者独立开来。setsid函数能够使进程完全独立出来,从而脱离所有其他进程的控制。
    (4)改变工作目录
    使用fork创建的子进程也继承了父进程的当前工作目录。由于在进程运行过程中,当前目录所在的文件系统不能卸载,因此,把当前工作目录换成其他的路径,如“/”或“/tmp”等改变工作目录的常见函数是chdir。
    (5)关闭文件描述符(0,1,2)
    用fork新建的子进程会从父进程那里继承一些已经打开了的文件。这些被打开的文件可能永远不会被守护进程读或写,但它们一样消耗系统资源,可能导致所在的文件系统无法卸载。
    (6)忽略SIGCHLD信号
     创建守护进程的时候fork一次和fork两次两者有什么区别 :
    (1)调用一次fork的作用:
        第一次fork的作用是让shell认为这条命令已经终止,不用挂在终端输入上,还有就是为了后面的setsid服务,因为调用setsid函数的进程不能是进程组组长,如果不fork出子进程,则此时的父进程是进程组组长,就无法调用setsid。当子进程调用完setsid函数之后,子进程是会话组长也是进程组组长,并且脱离了控制终端,此时,不管控制终端如何操作,新的进程都不会收到一些信号使得进程退出。
    (2)第二次fork的作用:
    虽然当前关闭了和终端的联系,但是后期可能会误操作打开了终端。
    只有会话首进程能打开终端设备,也就是再fork一次,再把父进程退出,再次fork的子进程作为守护进程继续运行,保证了该精灵进程不是对话期的首进程,
    第二次不是必须的,是可选的,市面上有些开源项目也是fork一次
    实现代码:
    #include<sys/types.h>
      #include<sys/stat.h>
     #include<unistd.h>
      #include<stdlib.h>
      #include<stdio.h>
        #include<signal.h>
       void mydaemon()                                                       
        {               
            pid_t id;   
             //重设文件创建 掩码      
           umask(0);   
             //创建子进程,终止父进程    
         id=fork(); 
        if(id>0)       
           {           
          //father 
                exit(1);
           }                       
          else                                                             
            //新建会话                    
          setsid();     
         //改变工作目录              
           chdir("/");   
            //关闭文件描述符              
           close(0);     
            close(1);     
           close(2);  
    // 忽略SIGCHLD信号  
           signal(SIGCHLD,SIG_IGN);
      }                 
       int main()
       {
          mydaemon();
       while(1);
         return 0;
      }  
    


    展开全文
  • 【Linux】守护进程守护进程创建

    千次阅读 2016-08-03 12:26:40
    守护进程 守护进程是生存期长的一种进程。它们常常在系统引导装入时... 下面我从守护进程结构,以及如何编写守护进程程序两方面分析守护进程守护进程的特征 我们使用ps -axj命令查看一些常用的系统守护进程
  • 1、什么是守护进程守护进程也称为精灵进程,是运行在后台进程的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。 (1)脱离于控制终端并且在后台运行 (2)不受用户登录注销的影响...
  • 守护进程

    2017-06-15 23:51:15
    什么是守护进程守护进程是运行在系统后台的一种特殊程序,独立于控制终端并且周期性的执行某种任务或者等待处理某些发生的事件。 守护进程也称为精灵进程,有以下特点: ...创建守护进程的关键就是创建新的Sess
  • 三:进程和守护进程 3.1 进程创建 3.2守护进程创建 四:选择线程还是进程 近期在工作中,遇到了Python的线程和守护线程的问题,中间还被一篇文章误导了,所以感觉有必要根据查到的资料和自己的实践...
  • 创建守护进程的步骤

    万次阅读 多人点赞 2018-08-03 21:30:55
    实现一个守护进程,其实就是将普通进程按照上述特性改造为守护进程的过程。 需要注意的一点是,不同版本的 Unix 系统其实现机制不同,BSD 和 Linux 下的实现细节就不同。 根据上述的特性,我们便可以创建一个简单的...
  • 【Linux】守护进程/精灵进程的创建

    千次阅读 多人点赞 2021-04-12 21:18:08
    守护进程也称精灵进程(Daemon),是运行在后台的一种特殊进程。守护进程独立于控制终端,它们常常跟随系统启动...要创建个守护进程,我们需要: 1.调用umask()函数,将文件模式创建屏蔽字设置为0 umask(0); //用uma
  • 守护进程和超级守护进程

    千次阅读 2015-01-02 11:09:00
    在Linux中,守护进程有...每个守护进程都会有一个脚本,可以理解成工作配置文件,守护进程的脚本需要放在指定位置,独立启动守护进程:放在/etc/init.d/目录下,当然也包括xinet的shell脚本;超级守护进程:按照x
  • 自己创建守护进程

    2016-07-20 13:06:29
    创建守护进程有两种方式,一种是通过系统提供的函数实现,另一种是模仿函数的底层实现。 (一)自己创建 1.调用umask将文件模式创建屏蔽字设置为0 2.调用fork,并且父进程退出 3.调用setsid创建新的会话 4....
  • linux创建守护进程

    千次阅读 2014-10-12 12:27:40
    一、概述  linux开启进程都是与终端绑定的,终端一关,进程也关,...如果想让某个进程不因为用户或终端或其他地变化而受到影响,那么就必须把这个进程变成一个守护进程。   二、守护进程特性  守护进程最重要的
  • 如何创建守护进程

    2015-09-10 23:00:42
     在linux或者unix操作系统中在系统的引导的时候会开启很服务,这些服务就叫做守护进程。为了增加灵活性,root可以选择系统开启的模式,这些模式叫做运行级别,每一种运行级别以一定的方式配置系统。  守护进程...
  • 守护进程概念,以及怎么创建守护进程

    万次阅读 多人点赞 2016-10-09 20:32:30
    一,守护进程概述 Linux Daemon(守护进程)是运行在后台的一种特殊进程。它独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件。它不需要用户输入就能运行而且提供某种服务,不是对整个系统就是对...
  • 守护进程介绍 Daemon()程序是一直运行的服务端程序,又称为守护进程。通常在系统后台运行,没有控制终端,不与前台交互,Daemon程序一般作为系统服务使用。Daemon是长时间运行的进程,通常在系统启动后就运行,在...
  • linux之创建守护进程

    千次阅读 2016-10-17 17:48:49
    其实,本质上守护进程和普通的进程并没有什么区别,只是我们规定了一种进程的编写规则,将其叫做守护进程,仅此而已。 特点1. 在后台运行 为了不让其阻塞终端,我们用fork()创建子进程,然后退出父进程,就可以...
  • 创建单实例守护进程

    2016-12-19 21:50:53
    在UNIX环境高级编程(APUE)中...根据APUE的介绍,创建守护进程基本需要如下7步骤。需要注意的是由于守护进程没有TTY(控制终端),所以代码中部分特意写上去的printf语句是不会输出到终端界面上的。 1 2

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 120,998
精华内容 48,399
关键字:

创建多个守护进程