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

嵌入式Linux并发程序设计,进程,会话、控制终端,守护进程创建骤,fork()/exit(),setsid(),chdir(),umask(),close(),转化系统时间为本地时间ctime()

2018-11-07 11:59 471 查看

文章目录

  • 守护进程示例
  • 1,守护进程

    1. 守护进程(Daemon)是Linux三种进程类型(交互进程、批处理进程、守护进程)之一
    2. 通常在系统启动时运行,系统关闭时结束
    3. Linux系统中大量使用,很多服务程序(网络服务、STTP服务、打印服务、NFS服务等)以守护进程形式运行

    2,守护进程的特点

    1. 始终在后台运行
    2. 独立于任何终端(既不能在终端输出,也不能在终端输入)
    3. 周期性的执行某种任务或等待处理特定事件

    3,会话、控制终端

    1. Linux以会话(session)、进程组的方式管理进程
    2. 每个进程属于一个进程组(运行一个程序的时候,系统创建了一个进程来执行这个程序,创建进程的时候同时创建了一个新的进程组。可以理解为每个运行的程序实际上对应一个进程组,当在程序中创建子进程时,子进程和父进程同属于一个进程组)
    3. 会话是一个或多个进程组的集合。通常用户打开一个终端时,系统会创建一个会话。所有通过该终端运行的进 程都属于这个会话(终端成为会话的控制终端,一个会话最多能打开一个控制终端,可以不打开)
    4. 终端关闭时,所有相关进程会被结束(所以守护进程和终端无关,这样守护进程才能不受终端影响)

    4,守护进程创建,五个步骤

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

    if (fork() > 0)
    {
    exit(0);
    }
    1. 子进程变成孤儿进程,被init进程收养
    2. 子进程在后台运行(子进程虽然在后台运行,但还依附于当前终端)

    b,子进程创建新会话setsid()

    if (setsid() < 0)
    {
    exit(-1);
    }
    1. 子进程成为新的会话组长
    2. 子进程脱离原先的终端

    c,更改当前工作目录chdir()

    chdir(“/”);//可以指向根目录
    
    chdir(“/tmp”);//也可以指向根目录下的tmp目录
    1. 守护进程一直在后台运行,其工作目录不能被卸载(守护进程在创建的时候,其当前工作工作目录可能指向任意一个目录,为了避免其所在的文件系统被卸载,一般都要把守护进程的当前工作目录设指向一个永远不需要被卸载的目录,比如“/”,“/tmp”)
    2. 重新设定当前工作目录cwd
    3. 对于普通用户来说,根目录可读、可执行,但是不能写
    4. 所有的用户在tmp下都是可读、可写、可执行的

    d,重设文件权限掩码umask()

    if (umask(0) < 0)
    {
    exit(-1);
    }
    1. 文件权限掩码设置为0*(守护进程有可能会创建新文件,一般不希望对守护进程创建的文件的权限加以限制)

    2. 只影响当前进程

      e,关闭打开的文件描述符close()

    int  i;
    for(i=0; i<getdtablesize(); i++)
    {
    close(i);
    }
    1. 关闭所有从父进程继承的打开文件(一个程序执行的时候,系统会自动打开标准输入、标准输出、标准错误三个流,这三个流都指向终端,而守护进程与终端无关,所以直接关掉。也可以重定向,把这三个流指向某个文件,然后从文件中输出或从文件中输入)
    2. 已脱离终端,stdin / stdout / stderr无法再使用

    守护进程示例

    创建守护进程,每隔1秒将系统时间写入文件time.log

    int  main()
    {
    pid_t pid;
    FILE *fp;
    time_t  t;
    int  i;
    
    if ((pid = fork()) < 0)//创建子进程
    {
    perror(“fork”);
    exit(-1);
    }
    else if (pid > 0)//关闭父进程
    {
    exit(0);
    }
    
    setsid();//创建新会话
    umask(0);//重设文件权限掩码
    chdir(“/tmp”);//更改当前工作目录
    for (i=0; i< getdtablesize(); i++) //关闭打开的文件描述符(从父进程继承的打开文件)
    {
    close(i);
    }
    if ((fp = fopen(“time.log”, “a”)) == NULL) {
    perror(“fopen”); exit(-1); }
    while  ( 1 ) {
    time(&t);
    fprintf(fp, “%s”, ctime(&t));//将获取的系统时间自动转化为本地时间
    fflush(fp);//强制刷新流
    sleep(1);
    }
    阅读更多
    内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
    标签: 
    相关文章推荐