- 当读到《Linux网络编程》的P33时,exec 和 fork() 联用
运行结果如下:
- 首先我们看下 perror 函数的使用:
perror( ) 函数原型:
#include <stdio.h>
void perror(const char *s);
其中 perror( ) 的参数字符串 s 是我们自己设定的,当调用这个函数的时候,会在标准输出上打印字符串,再跟上一个“冒号:”和空格,然后才是基于当前 errno 的值进行的错误类型描述。
perror( ) 函数是将上一条语句执行后的错误打印到标准输出上。
运行结果如下截图:在标准输出上打印了 test error: Success。所以程序执行的时候的 errno 值(int 类型)为 Success
errno 变量是系统变量,不需要我们赋值和声明,但如果要使用它,则需要加上 #include <errno.h> 头文件。
在这里我们可以看下“获取 errno 对应的错误描述 ”的程序:
运行结果如下截图所示,strerror( ) 函数在头文件 #include <string.h> 里面声明,该函数的形参是错误状态(int),返回值是形参对应的错误状态描述字符串。
这个函数可以理解为将 int 类型的错误状态转换为字符串。
- wait( ) 系统调用的使用
头文件:
#include <sys/types.h>
#include <sys/wait.h>
pid_t wait(int *status);
函数说明:
wait()会暂时停止目前进程的执行,直到有信号来到或子进程结束。 如果在调用 wait( ) 时子进程已经结束, 则wait( ) 会立即返回子进程结束状态值。子进程的结束状态值会由参数status 返回, 而子进程的进程识别码也会一快返回。 如果不在意结束状态值,则参数 status 可以设成NULL。
返回值:如果执行成功则返回子进程识别码(PID), 如果有错误发生则返回-1。失败原因存于errno 中。
进程一旦调用了 wait( ) 函数,就立即阻塞自己,由 wait 自动分析是否当前进程的某个子进程已经退出,如果让它找到了一个已经变为僵尸的子进程,wait 就会收集这个子进程的信息,并把它彻底销毁后返回;如果没有找到这样一个子进程,wait 就会一直阻塞在这里,直到有一个变为僵尸的子进程出现为止。
由wait( ) 函数声明可以知道,其形参是一个指向整数的指针,这个整数 (*status )可以指出子进程是正常退出还是非正常结束的(进程被其他进程信号结束为非正常结束),以及正常结束时的返回值,或被哪一个信号结束等信息。
而这些信息被保存在整数(*status)的不同二进制位中,所以用常规的方法读取会非常麻烦,人们就设计了一套专门的宏(macro)来完成这项工作,其中最常用的有
(1) WIFEXITED(*status) 这个宏是用来判断子进程是否为正常退出的,如果是,它会返回一个非零值。
(2) WEXITSTATUS(*status) 当 WIFEXITED(*status) 返回非零的时候,我们可以用这个宏来提取子进程的返回值,如果子进程调用 exit(5) 退出,WEXITSTATUS(status) 就会返回5,。如果进程不是正常退出的,WIFEXITED(status) 返回零,WEXITSTATUS 也就没有使用的必要了。
首先执行父进程中的代码,后父进程因为调用 sleep( ) 函数,暂时停止父进程的执行,接着子进程开始执行,使用exit(5)正常退出子进程,等到1s后,父进程开始执行,后使用 wait() 函数收集自己的僵尸子进程的信息,检测wait函数是否执行成功,执行成功后,判断这个子进程是正常退出的,正常退出后打印这个子进程的相关信息。
===============
参考链接:
说清这个程序的逻辑
perror() 和 strerror() 的应用和区别
wait() 函数的使用:
strerror(errno):获取errno对应的错误
Linux wait() 和 waitpid()函数介绍
C语言wait()函数:结束(中断)进程函数(常用)
C语言waitpid()函数:中断(结束)进程函数