• 正文
  • 相关推荐
申请入驻 产业图谱

飞凌嵌入式ElfBoard-文件I/O的了解探究之原子操作

11/27 13:30
221
加入交流群
扫码加入
获取工程师必备礼包
参与热点资讯讨论

原子操作指的是不可被中断或分割的基本操作,它在执行过程中要么完全执行成功,要么完全不执行,不会被其他并发操作所干扰。

原子操作是确保对共享资源进行并发访问时线程安全的关键,通常由硬件或操作系统提供支持,并且能够保证在多线程或多进程环境下的安全性。

常见的原子操作包括原子增加、原子减少、原子交换等。这些操作能够保证在并发执行时不会发生竞争冒险或数据竞争(Data Race),从而确保数据的一致性和完整性。

在并发编程中,原子操作通常用于保护共享资源的访问和修改,以防止多个线程同时访问或修改同一共享资源而导致的竞争冒险。使用原子操作能够简化并发编程的同步机制,并且能够提高程序的性能和效率。

例如:有两个应用程序 A和B,都对同一个文件进行写操作,进程A先写入,那么后写入的进程B就会把A写入的数据覆盖掉。

解决办法就是将“先定位到文件末尾,然后写”这两个步骤组成一个原子操作,由此引入pread和pwrite函数。

1.pread

用于带偏移量的从文件中读取数据,无法中断其定位和读操作,不更新文件表中当前的位置偏移量。

1)头文件

#include <unistd.h>

2)函数原型

ssize_t pread(int fd, void *buf, size_t count, off_t offset);

3)参数

fd:表示要操作文件的文件描述符。

buf:表示读出数据存放的位置(缓冲区地址)。

count:表示读出的字节数。

offset:表示当前需要进行读的位置偏移量。

4)返回值

若读取成功则返回实际读到的字节数,若已到文件结尾则返回0,若出错则返回-1。

5)示例:(带偏移量的从文件中读取特定数据,查看读取后的文件偏移量)

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <string.h>

#include <unistd.h>

#include <stdio.h>

int main(){

char bufwrite[30] = "HELLO WORLD!!!n";

char bufread[30];

int fd, lk;

fd = open("./test", O_RDWR | O_CREAT | O_TRUNC, 0666);  //打开文件test

if (fd < 0) {

printf("error: test openn");

return -1;

}

if ( write(fd, bufwrite, strlen(bufwrite)) < 0 ) {           //向文件test写入特定内容

printf("error: test writen");

close(fd);

return -1;

}

if (pread(fd, bufread, 3, 2) < 0) {                //读取2字节后的3字节内容

printf("error: test preadn");

close(fd);

return -1;

}

lk = lseek(fd, 0,SEEK_CUR);                //获取当前偏移量位置

if (lk < 0) {

printf("error: test lseekn");

close(fd);

return -1;

}

printf("pread fd:%s", bufread);

printf("lseek fd:%dn", lk);

close(fd);

return 0;

}

6)编译运行并查看测试结果

pread fd:LLO                   //读取到2字节后的3字节内容

lseek fd:15                     //第一次写入后的偏移量,而不是pread读取的位置

2.pwrite

用于带偏移量的向文件中写入数据,无法中断其定位和写操作,不更新文件表中当前的位置偏移量。

1)头文件

#include <unistd.h>

2)函数原型

ssize_t pwrite(intfd, const void *buf, size_tcount, off_toffset);

3)参数

fd:表示要操作文件的文件描述符。

buf:表示要写的数据(缓冲区地址)。

count:表示写入的字节数。

offset:表示当前需要进行写的位置偏移量。

4)返回值

成功,返回写入到文件中的字节数;失败,返回-1。

5)示例:(带偏移量的向文件写入特定数据,查看写入后的文件偏移量)

#include <sys/types.h>

#include <sys/stat.h>

#include <fcntl.h>

#include <unistd.h>

#include <stdio.h>

#include <string.h>

int main()

{

char bufwrite[30] = "HELLO WORLD!!!n";

char bufWrite[30] = "pwrite test!n";

char bufread[30];

int fd, lk;

fd = open("./test", O_RDWR | O_CREAT | O_TRUNC, 0666);

if (fd < 0) {

printf("error: test openn");

return -1;

}

if ( write(fd, bufwrite, strlen(bufwrite)) < 0 ) {     //向文件test写入特定内容

printf("error: test writen");

close(fd);

return -1;

}

if (pwrite(fd, bufWrite, strlen(bufWrite), 15) < 0) {

//带偏移量向文件test写入特定内容

printf("error: test preadn");

close(fd);

return -1;

}

if (pread(fd, bufread, 30, 5) < 0) {              //带偏移量读取test特定内容

printf("error: test preadn");

close(fd);

return -1;

}

lk = lseek(fd, 0, SEEK_CUR);

if(lk < 0) {

printf("error: test lseekn");

close(fd);

return -1;

}

printf("pread fd: %s", buf);

printf("lseek fd: %dn", lk);

close(fd);

return 0;

}

6)编译运行并查看测试结果

pread fd: WORLD!!!

pwrite test!

lseek fd: 15

相关推荐