博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
《UNIX环境高级编程(第3版)》——1.7 出错处理
阅读量:6865 次
发布时间:2019-06-26

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

本节书摘来自异步社区《UNIX环境高级编程(第3版)》一书中的第1章,第1.7节,作者:【美】W. Richard Stevens , Stephen A.Rago著,更多章节内容可以访问云栖社区“异步社区”公众号查看

1.7 出错处理

当UNIX系统函数出错时,通常会返回一个负值,而且整型变量errno通常被设置为具有特定信息的值。例如,open函数如果成功执行则返回一个非负文件描述符,如出错则返回1。在open出错时,有大约15种不同的errno值(文件不存在、权限问题等)。而有些函数对于出错则使用另一种约定而不是返回负值。例如,大多数返回指向对象指针的函数,在出错时会返回一个null指针。

文件中定义了errno以及可以赋与它的各种常量。这些常量都以字符E开头。另外,UNIX系统手册第2部分的第1页,intro(2)列出了所有这些出错常量。例如,若errno等于常量EACCES,表示产生了权限问题(例如,没有足够的权限打开请求文件)。

在Linux中,出错常量在errno(3)手册页中列出。

POSIX和ISO C将errno定义为一个符号,它扩展成为一个可修改的整形左值(lvalue)。它可以是一个包含出错编号的整数,也可以是一个返回出错编号指针的函数。以前使用的定义是:

extern int errno;

但是在支持线程的环境中,多个线程共享进程地址空间,每个线程都有属于它自己的局部errno以避免一个线程干扰另一个线程。例如,Linux支持多线程存取errno,将其定义为:

extern int *__errno_location(void);  #define errno (*__errno_location())

对于errno应当注意两条规则。第一条规则是:如果没有出错,其值不会被例程清除。因此,仅当函数的返回值指明出错时,才检验其值。第二条规则是:任何函数都不会将errno值设置为0,而且在中定义的所有常量都不为0。

C标准定义了两个函数,它们用于打印出错信息。

#include 
char *strerror(int errnum);                      返回值:指向消息字符串的指针

strerror函数将errnum(通常就是errno值)映射为一个出错消息字符串,并且返回此字符串的指针。

perror函数基于errno的当前值,在标准错误上产生一条出错消息,然后返回。

#include 
void perror(const char *msg);

它首先输出由msg指向的字符串,然后是一个冒号,一个空格,接着是对应于errno值的出错消息,最后是一个换行符。

实例

图1-8程序显示了这两个出错函数的使用方法。

#include "apue.h"#include 
intmain(int argc, char *argv[]){   fprintf(stderr, "EACCES: %s\n", strerror(EACCES));   errno = ENOENT;   perror(argv[0]);   exit(0); }

图1-8 例示strerror和perror

如果将此程序编译成文件a.out,然后执行它,则有

$ ./a.outEACCES: Permission denied./a.out: No such file or directory

注意,我们将程序名(argv[0],其值是./a.out)作为参数传递给perror。这是一个标准的UNIX惯例。使用这种方法,在程序作为管道的一部分执行时,例如:

prog1 < inputfile | prog2 | prog3 > outputfile

我们就能分清3个程序中的哪一个产生了一条特定的出错消息。

本书中的所有实例基本上都不直接调用strerror或perror,而是使用附录B中的出错函数。该附录中的出错函数使我们只用一条C语句就可利用ISO C的可变参数表功能处理出错情况。

出错恢复

可将在中定义的各种出错分成两类:致命性的和非致命性的。对于致命性的错误,无法执行恢复动作。最多能做的是在用户屏幕上打印出一条出错消息或者将一条出错消息写入日志文件中,然后退出。对于非致命性的出错,有时可以较妥善地进行处理。大多数非致命性出错是暂时的(如资源短缺),当系统中的活动较少时,这种出错很可能不会发生。

与资源相关的非致命性出错包括:EAGAIN、 ENFILE、 ENOBUFS、 ENOLCK、 ENOSPC、 EWOULDBLOCK,有时ENOMEM也是非致命性出错。当EBUSY指明共享资源正在使用时,也可将它作为非致命性出错处理。当EINTR中断一个慢速系统调用时,可将它作为非致命性出错处理(在10.5节对此会进行更多说明)。

对于资源相关的非致命性出错的典型恢复操作是延迟一段时间,然后重试。这种技术可应用于其他情况。例如,假设出错表明一个网络连接不再起作用,那么应用程序可以采用这种方法,在短时间延迟后,尝试重建该连接。一些应用使用指数补偿算法,在每次迭代中等待更长时间。

最终,由应用的开发者决定在哪些情况下应用程序可以从出错中恢复。如果能够采用一种合理的恢复策略,那么可以避免应用程序异常终止,进而就能改善应用程序的健壮性。

转载地址:http://mgkfl.baihongyu.com/

你可能感兴趣的文章
Sitecore Sitecore 8将营销工作化繁为简
查看>>
泰一指尚携手吉利汽车、丝蕴syoss荣获中国广告主金远奖
查看>>
业务需求不息 数据生命不止
查看>>
MWC新看点:5G网络从标准化向商业化迈进
查看>>
java命名规范
查看>>
《中国人工智能学会通讯》——2.20 专用的深度学习处理器
查看>>
管理员权限的凭证安全漏洞
查看>>
Forrester:云计算受大型企业欢迎
查看>>
“以病患为中心”的智能医疗服务开启数字化医疗新体验
查看>>
西门子楼宇自动系统出现中间人攻击漏洞CVE-2016-9154 本已发布通告可又悄悄撤除...
查看>>
存储技术专家预测2017年云存储采用率飙升
查看>>
《VMware Virtual SAN权威指南》一3.10 磁盘组的角色
查看>>
网易2018校招内推编程题 交错01串
查看>>
阿里云哪个业务增长最快?绝对不是云服务器!
查看>>
Prepack——JavaScript代码优化工具
查看>>
全球安全行业融资收购简报(2015年11月)
查看>>
【硬创邦】跟hoowa学做智能路由(二):从芯片开始
查看>>
扫脸付、VR付实现了, “KongFu”空付还远吗?
查看>>
2016网络安全威胁四大趋势:人才全球缺货
查看>>
福布斯:云计算有人气 但未到最佳状态
查看>>