exec函数族和守护进程

进程 – exec函数族

 进程调用exec函数族执行某个程序

进程当前内容被指定的程序替换

实现让父子进程执行不同的程序

  •  父进程创建子进程  
  • 子进程调用exec函数族  
  • 父进程不受影响

进程 – execl / execlp

#include  <unistd.h>  

int execl(const char *path, const char *arg, NULL);  

int execlp(const char *file, const char *arg,NULL);    

成功时执行指定的程序;

  • 失败时返回EOF  
  • path   执行的程序名称,包含路径  
  • arg…  传递给执行的程序的参数列表  
  • file   执行的程序的名称,在PATH中查找

进程创建 – execl(p) – 示例

#include <stdio.h>
#include <unistd.h>

int main(){

   printf("before exec\n");
   if(execlp("ls","ls","-a","-l","./",NULL)<0){
	perror("execl");
   }

}

进程 – execv / execvp

#include  <unistd.h>  

int execv(const char *path, char *const argv[]);  

int execvp(const char *file, char *const argv[]);  

  • 成功时执行指定的程序;
  • 失败时返回EOF  arg… 封装成指针数组的形式

进程创建 – execv(p) – 示例

#include <stdio.h>
#include <unistd.h>

int main(){
   char *agv[] = {"ls","-a","-l","./",NULL};

   if(execv("/bin/ls",agv)<0){
	perror("execv");
   }

}

进程 – system

  #include  <stdlib.h>  

int system(const char *command);    

  • 成功时返回命令command的返回值;
  • 失败时返回EOF  当前进程等待command执行结束后才继续执行

守护进程

  • 守护进程(Daemon Process)是Linux三种进程类型之一
  • 是 Linux 中的后台服务进程
  • 是一个生存期较长的进程,通常独立于控制终端并且周期性地执行某种任务或等待处理某些发生的事件

守护进程特点

  • 特殊的孤儿进程
  • 始终在后台运行
  • 独立于任何终端
  • 周期性的执行某种任务或等待处理特定事件

守护进程 –相关概念

  • 进程组(Process Group): 进程集合,每个进程组有一个组长(Leader),其进程 ID 就是该进程组 ID。
  • 会话(Session): 进程组集合,每个会话有一个组长,其进程 ID 就是该会话组 ID。
  • 控制终端(Controlling Terminal):每个会话可以有一个单独的控制终端,与控制终端连接的 Leader 就是控制进程(Controlling Process)。

守护进程创建

(一)

  • 创建子进程,父进程退出            

        if (fork() > 0)  {

                exit(0);      

        }

  •  子进程变成孤儿进程,被init进程收养  
  • 子进程在后台运行

(二)

  • 子进程创建新会话          

         if (setsid() < 0)  {        

        exit(-1);      

        }  

  • 子进程成为新的会话组长  
  • 子进程脱离原先的终端

(三)

  • 更改当前工作目录          

        chdir(“/”);      

        chdir(“/tmp”);  

  • 守护进程一直在后台运行,其工作目录不能被卸载  
  • 重新设定当前工作目录cwd

(四)

  • 重设文件权限掩码            

        if (umask(0) < 0)  {        

        exit(-1);      

        }  

  • 文件权限掩码设置为0  
  • 只影响当前进程

(五)

  • 关闭打开的文件描述符            

        int  i;      

        for(i=0; i<3; i++) {        

        close(i);      

        }  

  • 关闭所有从父进程继承的打开文件  
  • 已脱离终端,stdin / stdout / stderr无法再使用

守护进程 – 示例1

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

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/stat.h>
#include <time.h>

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< 3; 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);
    }
}

gdb调试多进程

gdb是安装在Linux系统下的调试工具,编译可执行文件时加上参数"-g"才可以被调试。

set follow-fork-mode child     设置GDB调试子进程

set follow-fork-mode parent   设置GDB调试父进程

set detach-on-fork  on/off    设置GDB跟踪调试单个进程或多个

on: 只调试父进程或子进程的其中一个(根据follow-fork-mode来决定),这是默认的模式

off:父子进程都在gdb的控制之下,其中一个进程正常调试(根据follow-fork-mode来决定),另一个进程会被设置为暂停状态。

info inferiors    显示GDB调试的进程

inferiors  进程序号(1,2,3....)  切换GDB调试的进程

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值