linux系统调用-PWRITE Linux系统调用号大全
liebian365 2024-10-27 13:20 18 浏览 0 评论
pwrite()函数是一个系统调用,用于在指定偏移量处向文件写入数据。与write()函数相比,pwrite()的优势在于它可以直接在文件的指定位置写入数据,而不改变文件的当前偏移量。这对于多线程环境中的文件操作尤其有用,因为它避免了因修改共享的文件偏移量而导致的竞争条件。
函数原型
pwrite()函数的原型定义在<unistd.h>头文件中,如下所示:
#include <unistd.h>
ssize_t pwrite(int fd, const void *buf, size_t count, off_t offset);
- 参数:
- fd: 文件描述符,指向要写入的文件。
- buf: 指向缓冲区的指针,该缓冲区包含了要写入文件的数据。
- count: 指定要写入的字节数。
- offset: 文件中的偏移量,从文件开头开始计算,指定从哪里开始写入数据。
- 返回值:
- 成功时,返回写入的字节数。
- 失败时,返回-1,并设置errno以指示错误原因。
使用场景
pwrite()函数特别适合以下场景:
- 多线程文件写入:在多线程程序中,不同的线程可能需要独立地向同一个文件的不同位置写入数据。使用pwrite()可以避免因修改共享的文件偏移量而导致的竞争条件。
- 数据库和日志文件:数据库和日志文件经常需要在文件的特定位置进行更新或添加新条目,pwrite()提供了一种高效的方式来实现这一点,而不需要改变文件的当前偏移量。
示例1
使用pwrite()向文件的指定位置写入数据:
#include <fcntl.h>
#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main() {
int fd;
const char *text = "Hello, pwrite!";
ssize_t numWritten;
// 打开(或创建)文件
fd = open("example.txt", O_WRONLY | O_CREAT, 0666);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 向文件的指定位置写入数据
numWritten = pwrite(fd, text, strlen(text), 10); // 从文件的第10个字节处开始写入
if (numWritten == -1) {
perror("pwrite");
close(fd);
exit(EXIT_FAILURE);
}
printf("Wrote %ld bytes\n", (long)numWritten);
close(fd);
return 0;
}
这个程序首先打开(如果不存在则创建)一个名为example.txt的文件,然后使用pwrite()向文件的第10个字节处开始写入字符串"Hello, pwrite!"。通过指定偏移量,pwrite()允许我们直接在文件的特定位置写入数据,而不影响文件的当前偏移量。
示例代码
这个例子使用了POSIX线程(pthread)来演示如何在多线程环境下安全地使用pwrite(),避免因修改共享的文件偏移量而导致的竞争条件。
#include <fcntl.h>
#include <unistd.h>
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
// 线程函数参数结构体
typedef struct {
int fd; // 文件描述符
off_t offset; // 写入的起始偏移量
const char* text; // 要写入的文本
} ThreadArg;
// 线程函数
void* threadFunc(void* arg) {
ThreadArg* threadArg = (ThreadArg*)arg;
ssize_t numWritten;
// 使用pwrite()在指定偏移量处写入数据
numWritten = pwrite(threadArg->fd, threadArg->text, strlen(threadArg->text), threadArg->offset);
if (numWritten == -1) {
perror("pwrite");
return (void*)1;
}
printf("Thread: wrote '%s' at offset %ld\n", threadArg->text, (long)threadArg->offset);
return (void*)0;
}
int main() {
int fd;
pthread_t t1, t2;
ThreadArg t1Arg, t2Arg;
// 打开(或创建)文件
fd = open("example.txt", O_WRONLY | O_CREAT, 0666);
if (fd == -1) {
perror("open");
exit(EXIT_FAILURE);
}
// 准备线程参数
t1Arg.fd = fd;
t1Arg.offset = 0; // 第一个线程从文件开头写入
t1Arg.text = "Hello from Thread 1";
t2Arg.fd = fd;
t2Arg.offset = 50; // 第二个线程从文件的第50个字节处开始写入
t2Arg.text = "Hello from Thread 2";
// 创建线程
if (pthread_create(&t1, NULL, threadFunc, &t1Arg) != 0) {
perror("pthread_create");
close(fd);
exit(EXIT_FAILURE);
}
if (pthread_create(&t2, NULL, threadFunc, &t2Arg) != 0) {
perror("pthread_create");
close(fd);
exit(EXIT_FAILURE);
}
// 等待线程完成
pthread_join(t1, NULL);
pthread_join(t2, NULL);
close(fd);
return 0;
}
说明
首先打开(如果不存在则创建)一个名为example.txt的文件。然后,它创建了两个线程,每个线程都有自己的写入文本和偏移量。第一个线程在文件的开头写入文本,而第二个线程在文件的第50个字节处开始写入文本。每个线程调用pwrite()来在指定的偏移量处写入数据,这样做可以确保即使在多线程环境下,写入操作也不会互相干扰,避免了因修改共享的文件偏移量而导致的竞争条件。
通过这种方式,pwrite()提供了一种安全且高效的方法来在多线程程序中向同一个文件的不同位置并发写入数据。
注意
- 使用pwrite()时,文件的当前偏移量不会改变,这对于并发访问同一文件非常有用。
- 与所有系统调用一样,使用pwrite()时应检查返回值以处理可能的错误情况。
相关推荐
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
-
明天,酒馆战棋就将迎来大更新,也聊了很多天战棋相关的内容了,趁此机会,给兄弟们穿插一篇构筑模式的卡组推荐!老规矩,我们先来看10职业胜率。目前10职业胜率排名与一周前基本类似,没有太多的变化。平衡补丁...
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
-
首先,程序中头文件的选择,要选择头文件,在文件中是没有对M_PI的定义的。选择:项目——>”XXX属性"——>配置属性——>C/C++——>预处理器——>预处理器定义,...
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
-
齐鲁网·闪电新闻5月24日讯酒后驾驶是对自己和他人生命安全极不负责的行为,为守护大家的平安出行路,东营交警一直将酒驾作为重点打击对象。5月23日,东营交警公布最新一批饮酒、醉酒名单。对以下驾驶人醉酒...
- Qt界面——搭配QCustomPlot(qt platform)
-
这是我第一个使用QCustomPlot控件的上位机,通过串口精确的5ms发送一次数据,再将读取的数据绘制到图表中。界面方面,尝试卡片式设计,外加QSS简单的配了个色。QCustomPlot官网:Qt...
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
-
老友相聚,仗剑江湖!《大话西游2》2021全民PK季4月激燃打响,各PK玩法鏖战齐开,零门槛参与热情高涨。PK季期间,不仅各种玩法奖励丰厚,参与PK趣闻录活动,投稿自己在PK季遇到的趣事,还有机会带走...
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
-
用ClaudeSonnet3.7的天气测试编码,让谷歌VSCodeAI编程插件GeminiCodeAssist自动编程。生成的文件在浏览器中的效果如下:(附源代码)VSCode...
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
-
前段时间DNF国服推出了名为“阿拉德B计划”的系列改版计划,截至目前我们已经看到了两项实装。不过关于便利性上,国服似乎还有很多路要走。自从顾爷回归DNF以来,几乎每天都在跟我抱怨关于DNF里面各种各样...
- 掌握Visual Studio项目配置【基础篇】
-
1.前言VisualStudio是Windows上最常用的C++集成开发环境之一,简称VS。VS功能十分强大,对应的,其配置系统较为复杂。不管是对于初学者还是有一定开发经验的开发者来说,捋清楚VS...
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
-
随着LED在各个领域的不同应用需求,LED驱动电路也在不断进步和发展。本文从LED的特性入手,推导出适合LED的电源驱动类型,再进一步介绍各类LED驱动设计。设计必读:LED四个关键特性特性一:非线...
- Visual Studio Community 2022(VS2022)安装图文方法
-
直接上步骤:1,首先可以下载安装一个VisualStudio安装器,叫做VisualStudioinstaller。这个安装文件很小,很快就安装完成了。2,打开VisualStudioins...
- Qt添加MSVC构建套件的方法(qt添加c++11)
-
前言有些时候,在Windows下因为某些需求需要使用MSVC编译器对程序进行编译,假设我们安装Qt的时候又只是安装了MingW构建套件,那么此时我们该如何给现有的Qt添加一个MSVC构建套件呢?本文以...
- Qt为什么站稳c++GUI的top1(qt c)
-
为什么现在QT越来越成为c++界面编程的第一选择,从事QT编程多年,在这之前做C++界面都是基于MFC。当时为什么会从MFC转到QT?主要原因是MFC开发界面想做得好看一些十分困难,引用第三方基于MF...
- qt开发IDE应该选择VS还是qt creator
-
如果一个公司选择了qt来开发自己的产品,在面临IDE的选择时会出现vs或者qtcreator,选择qt的IDE需要结合产品需求、部署平台、项目定位、程序猿本身和公司战略,因为大的软件产品需要明确IDE...
- Qt 5.14.2超详细安装教程,不会来打我
-
Qt简介Qt(官方发音[kju:t],音同cute)是一个跨平台的C++开库,主要用来开发图形用户界面(GraphicalUserInterface,GUI)程序。Qt是纯C++开...
- Cygwin配置与使用(四)——VI字体和颜色的配置
-
简介:VI的操作模式,基本上VI可以分为三种状态,分别是命令模式(commandmode)、插入模式(Insertmode)和底行模式(lastlinemode),各模式的功能区分如下:1)...
你 发表评论:
欢迎- 一周热门
- 最近发表
-
- “版本末期”了?下周平衡补丁!国服最强5套牌!上分首选
- VS2017 C++ 程序报错“error C2065:“M_PI”: 未声明的标识符"
- 东营交警实名曝光一批酒驾人员名单 88人受处罚
- Qt界面——搭配QCustomPlot(qt platform)
- 大话西游2分享赢取种族坐骑手办!PK趣闻录由你书写
- 测试谷歌VS Code AI 编程插件 Gemini Code Assist
- 顾爷想知道第4.5期 国服便利性到底需优化啥?
- 掌握Visual Studio项目配置【基础篇】
- 还嫌LED驱动设计套路深?那就来看看这篇文章吧
- Visual Studio Community 2022(VS2022)安装图文方法
- 标签列表
-
- wireshark怎么抓包 (75)
- qt sleep (64)
- cs1.6指令代码大全 (55)
- factory-method (60)
- sqlite3_bind_blob (52)
- hibernate update (63)
- c++ base64 (70)
- nc 命令 (52)
- wm_close (51)
- epollin (51)
- sqlca.sqlcode (57)
- lua ipairs (60)
- tv_usec (64)
- 命令行进入文件夹 (53)
- postgresql array (57)
- statfs函数 (57)
- .project文件 (54)
- lua require (56)
- for_each (67)
- c#工厂模式 (57)
- wxsqlite3 (66)
- dmesg -c (58)
- fopen参数 (53)
- tar -zxvf -c (55)
- 速递查询 (52)