系统编程 笔记7

gdb调试:
1.set follow-fork-mode child 命令设置gdb在fork之后跟踪子进程
2.set follow-fork-mode prarent 设置跟踪父进程

exec函数族:
简单来说就是当程序执行了fork()(此时程序分出父进程),默认情况下父进程有的代码子进程也有,但是如果有了exec这个函数,子进程中的所有代码会被清空,去执行你指定的一个程序,比如写了exec(a.out),那么子进程将执行的是a.out这个程序。
但是子进程PID没有变,还是父进程的儿子,只是它的灵魂变了。
execlp函数:
实例:execlp(“ls”, “-l”, “-d”, “-h”, NULL);
我想让子进程执行ls命令且在后面跟了若干参数,参数可以任意指定但是需要告诉函数我的参数到哪为止,其中NULL就是告诉函数参数没有了。
函数原型:int execlp(const char *file, const char *arg, …);
关于函数返回值:通过man此函数,只有当函数出错时会返回一个 -1 和 设置errno。
根据实际运行来看,实例代码基本没有现象,这是因为参数有误,因为参数调用是从argv[0]开始的,比如:./a.out aa bb cc 其中第一个参数是a.out,而实例中将“-l”设置成了第一个参数。
修改后:execlp(“ls”, “ls”, “-l”, “-h”, NULL);
这里删除了“-d,因为“-d”只显示当前目录不显示其下面的文件所以现象不明显(只会打印出一个".")。
扩展:这里父进程的父进程就是bash,它执行它的子进程,也是通过exec函数来完成的。

execl函数:
函数原型:int execl(const char *path, const char *arg, …);
可以从参数看出和上面那个函数差别在于execl函数需要指定路径,而execlp函数只需指定文件名即可。其它一样。
实例:execl("./a,out", “./a.out”, NULL);//有参数加参数没有参数就这样
如果要执行“ls”,那么写法将是:execl("/bin/ls", “ls”, “-l”, NULL);这也可以看出差别。

execvp函数:
和execlp函数差别在于,将参数部分封装在一起了
实例:
1.execlp(“ls”, “ls”, “-l”, “-h”, NULL);

2.char *argv[] = { “ls”, “-l”, “-h”, NULL} ;
execvp(“ls”, argv);

函数原型:int execvp(const char *file, char *const argv[]);

exec函数族调用成功就执行新的程序不返回,所以只在出错时返回。此函数以上举得例子都是子进程中执行就是

if(pid == 0)
{
    exec........;//函数写在这里
}

回收子进程:

**孤儿进程:**父进程先于子进程结束,子进程变成了孤儿,此时子进程的父进程将变成init,init进程领养了子进程。实质就是进程回收

**僵尸进程:**进程终止,父进程尚未回收,子进程残留资源(PCB)存放于内核中,变成了僵尸进程。子进程在回收之前都处于僵尸态。因为子进程结束后是不能立马被回收的。比如父进程在一直死循环,此时子进程结束父进程是不能正常回收的,且父进程没有结束那么子进程就不能被init收养,从而变成了僵尸进程。

僵尸进程不能被kill,所以需要先kill了它的父进程,这样这个僵尸进程就变成了了孤儿进程,这样就可以被init收养,但是init发现收养的是一个僵尸随即就将它回收了,从而达到了回收的效果。

wait函数:
1.阻塞等待子进程退出
2.回收子进程残留资源
3.获取子进程结束状态(退出的原因)
原型:pid_t wait(int *status);
参数:回收进程的状态
成功返回:子进程ID
失败返回:-1
实例:
1.wait(&status)//可以获取子进程结束原因
2.wait(NULL)//不关心子进程的结束原因

它的返回值需要运用到宏函数进行操作,可以在man里查看

   WIFEXITED(status)//为真说明子进程正常终止
          returns true if the child terminated normally, that is, by call‐
          ing exit(3) or _exit(2), or by returning from main().

   WEXITSTATUS(status)//获取退出的状态(exit状态)
          returns  the  exit  status  of  the child.  This consists of the
          least significant 8 bits of the status argument that  the  child
          specified  in  a  call to exit(3) or _exit(2) or as the argument
          for a return statement in main().  This macro should be employed
          only if WIFEXITED returned true.

   WIFSIGNALED(status)//为真说明子进程被信号终止
          returns true if the child process was terminated by a signal.

   WTERMSIG(status)//取得暂停程序的那个信号编号,如:kill -11 。。。则返回11
          returns  the  number of the signal that caused the child process
          to terminate.  This macro should be employed only if WIFSIGNALED
          returned true.

可以在指令中输入:kill -l 看信号编号的宏长什么样

 1) SIGHUP	 2) SIGINT	 3) SIGQUIT	 4) SIGILL	 5) SIGTRAP
 6) SIGABRT	 7) SIGBUS	 8) SIGFPE	 9) SIGKILL	10) SIGUSR1
11) SIGSEGV	12) SIGUSR2	13) SIGPIPE	14) SIGALRM	15) SIGTERM
16) SIGSTKFLT	17) SIGCHLD	18) SIGCONT	19) SIGSTOP	20) SIGTSTP
21) SIGTTIN	22) SIGTTOU	23) SIGURG	24) SIGXCPU	25) SIGXFSZ
26) SIGVTALRM	27) SIGPROF	28) SIGWINCH	29) SIGIO	30) SIGPWR
31) SIGSYS	34) SIGRTMIN	35) SIGRTMIN+1	36) SIGRTMIN+2	37) SIGRTMIN+3
38) SIGRTMIN+4	39) SIGRTMIN+5	40) SIGRTMIN+6	41) SIGRTMIN+7	42) SIGRTMIN+8
43) SIGRTMIN+9	44) SIGRTMIN+10	45) SIGRTMIN+11	46) SIGRTMIN+12	47) SIGRTMIN+13
48) SIGRTMIN+14	49) SIGRTMIN+15	50) SIGRTMAX-14	51) SIGRTMAX-13	52) SIGRTMAX-12
53) SIGRTMAX-11	54) SIGRTMAX-10	55) SIGRTMAX-9	56) SIGRTMAX-8	57) SIGRTMAX-7
58) SIGRTMAX-6	59) SIGRTMAX-5	60) SIGRTMAX-4	61) SIGRTMAX-3	62) SIGRTMAX-2
63) SIGRTMAX-1	64) SIGRTMAX

waitpid函数:
函数原型:pid_t waitpid(pid_t pid, int *status, int options);

返回值:

  1. 大于0的值:表示回收成功的子进程ID
  2. 0:函数调用时, 参数3指定WNOHANG,并且没有子进程结束
  3. -1:失败
    WNOHANG return immediately if no child has exited.//这个宏的意思是如果没有子进程结束立刻返回,就是非阻塞。

参数pid:

  1. 大于0:回收指定ID的子进程(如果取反则回收的是一个组,一般情况是这个子进程下面还有一系列的子进程)
  2. -1:回收任意子进程
  3. 0:回收和当前调用waitpid一个(进程组)的所有子进程
  4. 小于-1:回收指定进程组内的任意子进程
    不论是wait还是waitpid都只能回收一个进程。
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值