APUE---chap3文件I/O---原子操作

一. 多线程带来的文件读写问题

  • 考虑下面这种情况,单进程去读写文件没有什么问题
#include <fcntl.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h>
#include "stdio.h"

int main() {
    int fd = open("Person.cpp", O_RDWR);
    if (lseek(fd, 0L, 2) < 0) // 定位到文件末尾
        perror("lseek error");
    char buff[10] = {
        '1', '1', '1', '1', '1', '1', '1', '1', '1', '1',
    };
    if (write(fd, buff, 10) != 10) //写入buff的数据
        perror("write error");
}

如果我们有两个进程同时对这个文件进行写入。A进程使用lseek对文件末尾字节进行写入,B进程也使用lseek对文件末尾进行写入。本来AB进程的目的都是想在文件的尾端进行写入,如果此时某个进程先执行,那么文件的内容增加,另外一个内容再去写入时就不会在尾端写入了,而是插入。这就是多线程带来的问题。

  • 所以关键的问题是:我们希望某个线程去写,保存文件是一个不可以被其他线程打断的操作。就是说希望A线程打开-->写-->完成,这三个动作是一起的不会被打断的动作。

二. 原子操作(atomic operation)

概念:原子操作指的是不会被多线程打断的一个最小操作集合。

比如对某一段代码加锁,那么lock()与unlock()之间的代码就不会被其他线程打断。

三. 用pread()/pwrite()解决多线程的读写问题

pread()和pwrite()就是原子函数,不用考虑“一”中出现的多线程读写一个问题带来的问题。

#include <unistd.h>
ssize_t pread(int fd, void *buf, size_t nbytes, off_t offset);

ssize_t pwrite(int fd, const void *buf, size_t nbytes, off_t offset);

用法和read/write差不多,不过需要其他的参数。

上一篇:7段数码管绘制(尾号0,1)


下一篇:7段数码管绘制