Unix(Linux)中的原子操作

下面的文章是通过学习《Unix环境高级编程》总结的,内容摘抄或改自原书。
提到原子操作,首先想到的是这个操作是不可分割,不可中断的。在多进程(线程)过程中经常会出现写文件冲突这种头疼的情况。

Unix(Linux)中定义的原子操作能够解决这类的冲突。原子操作指的是由多步组成的操作,如果该操作原子的执行,则或者执行完所有步,或者一步也不执行,不可能只执行所有步的一个子集。

下面通过Unix的系统调用来看一下原子操作的好处:

  我们需要编写一个函数,用来在文件末尾添加内容,下列代码可以实现:

[cpp]  view plain copy
  1. int fd;  
  2. if((fd = open("test.txt", O_RDWR))==-1)  
  3.   printf("fd error");  
  4. if(lseek(fd, 0, SEEK_END) == -1)//首先将指针移到文件末尾  
  5.   printf("seek error");  
  6. if((write(fd, buf, 9)) != 9)//根据传过来的buf,写入文件  
  7.    printf("write error");  
这段代码中存在一个问题,当多个进程操作同一个文件,并且同时执行这一段代码的时候,进程1执行完lseek后,进程1的所对应的文件偏移量值为文件的end;此时,CPU将时间片分为进程2,进程2执行lseek后,接着执行完write函数,将buf中的内容写入文件,写入完成后将时间片返还给进程1,此时进程1接着执行write函数,对文件进行写入,因为进程1对应的偏移量是之前文件的末尾,所以进程1文件的写入会将进程2写入的文件给覆盖掉。这样造成了写入冲突的后果!

Unix提供了原子操作可以解决上述问题,该原子操作可以看作是将上述的两个操作封装而成的。其方法就是打开文件(open)时设置O_APPEND标志,这使得内核在每次对文件进行写入之前,都将进程的当前位移量设置到该文件的尾端处,于是在每次写之前就不需要使用lseek了。

你可能感兴趣的:(编程,linux,unix)