我应该使用什么同步机制来独占访问boost中的文本文件?该文件可能仅由一个进程的线程访问。
3 回答
文件锁定 API 通常用于进程间锁定。如果您在单个进程中,则Boost.Thread 包中适合您需要的所有内容都可以。应该使用Boost.Interprocess的外部进程。您可能想从 Boost.Interprocess 阅读以下警告:
注意:同步限制
如果您打算像命名互斥锁一样使用文件锁,请小心,因为可移植文件锁具有同步限制,主要是因为不同的实现(POSIX、Windows)提供不同的保证。进程间文件锁有以下限制:
- 如果 a
file_lock
同步来自同一进程的两个线程,则未指定。 - 一个进程是否可以使用
file_lock
指向同一个文件的两个对象是未指定的。
第一个限制主要来自 POSIX,因为文件句柄是每个进程的属性,而不是每个线程的属性。这意味着如果一个线程使用一个file_lock
对象来锁定一个文件,其他线程将看到该文件被锁定。另一方面,Windows 文件锁定机制提供线程同步保证,因此试图锁定已锁定文件的线程会阻塞。
第二个限制来自文件锁定同步状态与 Windows 中的单个文件描述符相关联的事实。这意味着如果创建了两个指向同一个文件的 file_lock 对象,则不能保证同步。在 POSIX 中,当一个描述符被关闭时,当使用两个文件描述符来锁定一个文件时,调用进程设置的所有文件锁都会被清除。
总而言之,如果您打算在进程中使用文件锁定,请使用以下限制:
file_lock
对于每个文件,每个进程使用一个对象。- 使用相同的线程来锁定和解锁文件。
- 如果您在对该文件使用文件锁的同时使用 std::fstream/native 文件句柄写入文件,请在释放文件的所有锁之前不要关闭该文件。
inline bool acquire_file_lock(file_handle_t hnd)
{
struct ::flock lock;
lock.l_type = F_WRLCK;
lock.l_whence = SEEK_SET;
lock.l_start = 0;
lock.l_len = 0;
return -1 != ::fcntl(hnd, F_SETLKW, &lock);
}
它与lock 的非增强实现一致。
struct flock fl = {F_WRLCK, SEEK_SET, 0, 0, 0 };
int fd;
fl.l_pid = getpid();
if (argc > 1)
fl.l_type = F_RDLCK;
if ((fd = open("lockdemo.c", O_RDWR)) == -1) {
perror("open");
exit(1);
}
printf("Press <RETURN> to try to get lock: ");
getchar();
printf("Trying to get lock...");
if (fcntl(fd, F_SETLKW, &fl) == -1) {
perror("fcntl");
exit(1);
}
printf("got lock\n");
printf("Press <RETURN> to
如果您确定只能从一个进程访问它,那么在线程本地存储中使用文件句柄的读写锁可能是一种解决方案。这将模拟上述情况,只有一个作者,但有几个读者。