gpt4 book ai didi

c++ - mutex 或 flock fcntl.h 只锁定写操作

转载 作者:太空宇宙 更新时间:2023-11-04 09:20:42 24 4
gpt4 key购买 nike

我正在尝试从不同的线程(类似于日志记录)追加(写入追加)到一个文件,因此不需要进程间锁定。

我研究了 fcntl.h 中的 flock,它说 flock 可以与进程间一起进行粒度锁定,这在我的情况下不是必需的。

char* file = "newfile.txt";
int fd;
struct flock lock;

printf("opening %s\n", file);
fd = open(file, O_APPEND);
if (fd >= 0) {
memset(&lock, 0, sizeof (lock));
lock.l_type = F_WRLCK;
fcntl(fd, F_SETLKW, &lock);
//do my thing here
lock.l_type = F_UNLCK;
fcntl(fd, F_SETLKW, &lock);
close(fd);
}

它可以进行粒度锁定和进程间锁定,是否会有开销?有锁时程序崩溃怎么办?

我目前的偏好是互斥,

static std::mutex fileMutex;
fileMutex.lock();
//do my thing here
fileMutex.unlock();

是否可以使用互斥方法,因为同步(或锁定)仅在进程(仅多线程)内需要,

或者在fcntl.h中用flock实现代码可以吗?

最佳答案

您可能不需要任何锁定。

使用 O_APPEND 标志设置您的 open() 调用,正如@Jean-BaptisteYunès 在评论中提到的那样。

然后使用单个 write() 调用写入您的数据。 POSIX 保证如果文件以附加模式打开,则单个 write() 操作将是原子的。 Per the POSIX standard :

If the O_APPEND flag of the file status flags is set, the file offset shall be set to the end of the file prior to each write and no intervening file modification operation shall occur between changing the file offset and the write operation. [emphasis mine]

您唯一的问题是如何处理部分 write() - 其中单个 write() 操作不会写入所有请求的数据。该标准要求每个 write() 操作都是原子操作 - 它不保证写入 34 MB 的请求将导致写入整个 34 MB。根据我的经验,直到 write() 调用请求移动大量字节之前,对实际文件的部分 write() 调用根本不会发生 - 我从未观察到部分write()文件 的任何单个 IO 操作的结果小于 1 MB - 我已经为很多大型组织完成了 SAN 安装和基准测试。

因此,如果您将 write() 调用限制在 PIPE_BUF 或更少字节(在 Linux 上),您几乎肯定可以避免所有锁定并让内部锁定进入内核解决了你的问题。

有关详细信息,请参阅以下内容:

Is file append atomic in UNIX?

请务必阅读那里链接的问题。

关于c++ - mutex 或 flock fcntl.h 只锁定写操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42203900/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com