博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
chdir改变当前目录以及理解守护进程为何fork()两次?
阅读量:4167 次
发布时间:2019-05-26

本文共 1817 字,大约阅读时间需要 6 分钟。

 /* 父进程退出 */

    if (fork() != 0)
    {
        exit(1);
    }
    
    if (setsid() < 0)
    {
        exit(1);
    }
    
    if (fork() != 0)
    {
        exit(1);
    }
sprintf(app_dir_path, "%s/%s", WORK_DIR_PATH, APP_DIR_PATH);
    if (chdir(app_dir_path) == -1)
    {
printf("chdir %s failed,taskd exit!\n",app_dir_path);
        exit(1);

    }

为什么fork两次?

1进程组首进程不能调用setsid,会得到EPERM错误,这就是第一个fork的原因,执行第一个fork并让父进程退出,子进程继续,这时候由于子进程会继承其父进程的进程组GID并有自己的进程PID,而这个PID和GID肯定是不一样的。所子进程绝不可能成为进程组首进程,满足了调用setsid的条件。
2调用setsid后所有到之前控制终端的连接都会断开。

最后,再执行一次fork,让子进程退出,孙进程继续。这样让孙进程pid不等于它所在的会话sid,这样它就不会自己变成会话首进程,也就使它不能打开控制终端。这样守护进程就得到了一个干净的环境,它不会被终端产生的信号干扰。
经过前面2个步骤,基本想要做的都做了。第2次fork不是必须的。也看到很多开源服务没有fork第二次。fork第二次主要目的是。防止进程再次打开一个控制终端。因为打开一个控制终端的前台条件是该进程必须是会话组长。再fork一次,子进程ID != sid(sid是进程父进程的sid)。所以也无法打开新的控制终端。

(chdir(app_dir_path)  产生的此子进程或孙进程可能不在/home/app里面工作,需要重新更改工作目录

理解:此程序是守护进程的部分代码,

1、在实际应用中,代码需要从当前目录进到其它目录,完成操作,然后再回到当前目录。这个时候需要getcwd获取当前目录路径,保存起来,在使用chdir跳转到其它目录,然后再使用chdir和保存的路径回到最初的目录。

2、man chdir

3、int  chdir(const char *path);

   -参数*path;文件路径

   -返回值;成功返回0,错误返回-1.

4、例:

[cpp]   
  1. #include <stdio.h>  
  2. #include <sys/types.h>  
  3. #include <sys/stat.h>  
  4. #include <fcntl.h>  
  5. //chdir和fchdir函数头文件  
  6. #include <unistd.h>  
  7.   
  8. #define LENTH 255  
  9.   
  10. int main(int argc,char *argv[])  
  11. {  
  12.     int ret;  
  13.     char pwd[LENTH];  
  14.   
  15. //检测参数    
  16.     if(argc <3){  
  17.         printf("\nPlease input file path\n");  
  18.         return 1;  
  19.     }  
  20.       
  21. //getcwd函数获取当前目录          
  22.     if(!getcwd(pwd,LENTH)){  
  23.         perror("getcwd");  
  24.         return 1;  
  25.     }  
  26.     printf("\ngetcwd pwd is %s\n",pwd);  
  27.       
  28. //使用chdir函数转入其他目录  
  29.     ret = chdir(argv[1]);  
  30.     if(ret){  
  31.         printf("Please make sure file path\n");  
  32.         return 1;  
  33.     }  
  34.     printf("chdir %s is success!\n",argv[1]);  
  35.       
  36. //转入其他目录,完成操作  
  37. //使用rmdir函数删除目录  
  38.     ret = rmdir(argv[2]);  
  39.     if(ret<0){  
  40.         printf("rmdir %s failed!\n",argv[2]);  
  41.         return 1;  
  42.     }  
  43.     printf("rmdir %s is success!\n",argv[2]);  
  44.       
  45. //再次使用chdir回到pwd保存的目录  
  46.     ret = chdir(pwd);  
  47.     if(ret){  
  48.         printf("Please make sure file path\n");  
  49.         return 1;  
  50.     }  
  51.     printf("chdir %s is success!\n",pwd);  
  52.   
  53.     return 0;  
  54. }  
你可能感兴趣的文章
flex常用网站
查看>>
flex 页面跳转
查看>>
cat | wc -l 少一行的问题
查看>>
socket 科普文章
查看>>
Mutex, semaphore, spinlock的深度解析
查看>>
pthread线程使用小结
查看>>
A Game of Thrones(59)
查看>>
2018.3.19
查看>>
A Game of Thrones(97)
查看>>
A Game of Thrones(98)
查看>>
2018.3.20
查看>>
2018.3.21
查看>>
2018.3.22
查看>>
2018.3.23
查看>>
A Game of Thrones(102)
查看>>
2018.4.29
查看>>
2018.4.30
查看>>
2018.4.31
查看>>
2018.4.32
查看>>
2018.4.33
查看>>