错误处理机制perror的详解

本文详细介绍了Linux系统中的错误处理机制,特别是perror函数如何根据errno值打印错误信息。当系统调用如open失败时,errno会被设置为对应错误编号。通过perror或strerror可以将错误编号转化为易读的错误信息。文中提供了一个示例代码,演示了如何使用这些错误处理方法来检查文件打开失败的具体原因。

open打开文件失败的原因,Linux系统会去设置errno的值 (整型的全局变量)

perrno会根据errno值(整型的全局变量)打印对应的错误信息

 

其实 errno是一个错误编号,当错误发生时,每一个不同的错误都有一个编号,这个编号的值就会被存储在errno中,perrorh会根据这错误编号判断是什么错误发生了,并且打印对应的错误信息,打印错误信息的函数有perror(),strerror(),printf("%m")等。

 

 打印错误信息

打印错误信息 / perror

void perror(const char *s)//打印系统错误信息

参数:

s: 字符串提示符

输出形式:

输出error值对应的错误信息

字符串显示错误信息 / strerror

函数原型:

char *strerror(int errnum);//将错误码以字符串的信息显示出来

参数:

errnum: 即errno

返回值:

返回错误码字符串信息

 

在讲解liunx错误处理机制之前我们先来看一段代码:

#include<sys/stat.h>

#include<unistd.h>

#include<sys/type.h>

#include<stdio.h>

#include<error.h>

 

int main(void){

int fd=open("test",O_WRONLY);//打开test文件,如果失败,系统会去设置全局变量error的值

if(fd<0){//打开失

文件锁机制是一种用于控制多进程或多线程对共享文件并发访问的技术,通过加锁和解锁操作确保数据的一致性和完整性。以下是文件锁机制的详细说明: ### 一、文件锁的类型 1. **强制性锁(Mandatory Locking)** 由操作系统强制执行,即使进程未主动检查锁状态,也无法修改被锁定的文件区域。需在文件系统挂载时启用(如Linux的`mand`选项),较少使用。 2. **建议性锁(Advisory Locking)** 依赖进程主动检查锁状态,若进程忽略锁,仍可能访问被锁定的文件。Unix/Linux默认使用建议性锁,通过`flock()`或`fcntl()`实现。 ### 二、文件锁的粒度 1. **整个文件锁** - 锁定整个文件,适用于需要独占访问的场景(如配置文件更新)。 - 示例:`flock(fd, LOCK_EX)`锁定整个文件。 2. **区域锁(Record Locking)** - 锁定文件的特定字节范围,允许多进程并发访问文件的不同部分。 - 通过`fcntl()`的`F_SETLK`、`F_SETLKW`等命令实现,需指定偏移量和长度。 ### 三、文件锁的实现方式 #### 1. `flock()` 函数(BSD风格) - **特点**:对整个文件加锁,简单但粒度粗。 - **锁类型**: - `LOCK_SH`:共享锁(读锁),多个进程可同时持有。 - `LOCK_EX`:排他锁(写锁),仅一个进程可持有。 - `LOCK_UN`:释放锁。 - `LOCK_NB`:非阻塞模式,若无法立即获取锁则返回错误。 - **示例代码**: ```c #include <sys/file.h> #include <fcntl.h> #include <unistd.h> int main() { int fd = open("example.txt", O_RDWR); if (fd == -1) { perror("open"); return 1; } // 尝试获取排他锁(非阻塞) if (flock(fd, LOCK_EX | LOCK_NB) == -1) { perror("flock"); printf("文件已被锁定。\n"); close(fd); return 1; } // 操作文件... printf("文件已锁定,可安全操作。\n"); // 释放锁 flock(fd, LOCK_UN); close(fd); return 0; } ``` #### 2. `fcntl()` 函数(System V风格) - **特点**:支持区域锁,灵活性更高。 - **锁类型**: - `F_RDLCK`:共享读锁。 - `F_WRLCK`:排他写锁。 - `F_UNLCK`:释放锁。 - `F_SETLK`:非阻塞加锁。 - `F_SETLKW`:阻塞加锁,直到成功。 - **结构体**: ```c struct flock { short l_type; // 锁类型(F_RDLCK/F_WRLCK/F_UNLCK) short l_whence; // 基准位置(SEEK_SET/SEEK_CUR/SEEK_END) off_t l_start; // 起始偏移量 off_t l_len; // 锁定长度(0表示到文件末尾) pid_t l_pid; // 持有锁的进程ID(仅由内核填充) }; ``` - **示例代码**: ```c #include <fcntl.h> #include <unistd.h> int main() { int fd = open("example.txt", O_RDWR); if (fd == -1) { perror("open"); return 1; } struct flock fl = { .l_type = F_WRLCK, .l_whence = SEEK_SET, .l_start = 0, .l_len = 100, // 锁定前100字节 }; // 尝试获取排他锁(非阻塞) if (fcntl(fd, F_SETLK, &fl) == -1) { perror("fcntl"); printf("文件区域已被锁定。\n"); close(fd); return 1; } // 操作文件... printf("文件区域已锁定,可安全操作。\n"); // 释放锁 fl.l_type = F_UNLCK; fcntl(fd, F_SETLK, &fl); close(fd); return 0; } ``` ### 四、文件锁的特性 1. **锁的继承与释放** - 锁与文件描述符关联,关闭文件描述符时自动释放锁。 - `fork()`创建的子进程继承父进程的锁,但`exec()`后锁通常会被释放(取决于实现)。 2. **死锁避免** - 避免多个进程互相等待对方释放锁,可通过超时机制或锁顺序策略解决。 3. **与信号量的区别** - 文件锁用于文件访问控制,信号量用于进程间同步。 ### 五、实际应用场景 1. **数据库系统**:防止多个事务同时修改同一数据文件。 2. **日志文件**:确保日志写入操作的原子性。 3. **配置文件**:避免多个进程同时修改配置导致冲突。 ### 六、注意事项 1. **锁的粒度选择**:根据需求选择整个文件锁或区域锁,避免过度锁定。 2. **错误处理**:始终检查`flock()`和`fcntl()`的返回值,处理`EAGAIN`(非阻塞模式下锁被占用)或`EDEADLK`(死锁)等错误。 3. **跨平台兼容性**:Windows使用`LockFileEx()`等API,与Unix/Linux的锁机制不兼容。
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值