我们写的程序,如果在Linux平台上只运行一个实例,且只有一个线程,基本上我们不用关心这个问题,open文件,read读write写文件,一切会按步就班的发生,不会有什么问题。
可这毕竟不是现实。现实是程序可能运行多个实例,一个实例可能有多个线程。特别是一些在线服务器程序,极有可能某个文件在同一时刻,被成千上万个read/write请求暴击,每个请求都争着获得它所需要的文件,多个进程或线程产生了竞争现象。并发与负载均衡,本文不谈这类高大上的话题,单从系统编程的角度来看等这件事。
1 原子操作与竞争条件
原子操作(atomic operation)指的是由多步操作组成的一个操作,要么执行完所有步骤,要么一步也不执行,不可能只执行所有步骤的一个子集。数据库中的事务处理和回卷,也类似于这个操作。
Linux系统编程中,所有的系统调用都是以原子操作方式执行的。内核保证了某系统调用中所有步骤会作为独立操作而一次性加以执行,期间不会为其他进程或者线程所中断。
原子操作的特性是操作系统调用得以正确执行的必要条件(不光是Linux,其它大型操作系统也一样)。它成功避免了"竞争",使两个(或多个)进程或线程,有序取得CPU的使用权,产生可预期的结果。
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <fcntl.h>
#include <errno.h>
int main(int argc ,char *argv[])
{
int fd;
char proc_id[64];
if ( ( argc < 2) || ( strcmp(argv[1],"--help") == 0 ) )
{
printf("请输入:命令 文件名 睡眠秒数\n") ;
exit(1);
}
fd = open(argv[1], O_WRONLY); // 没有使用O_EXCL情况
if (fd > 0) //Open succeeded
{
printf("[PID %ld] 文件 \"%s\" 已经存在