2

我应该使用什么同步机制来独占访问boost中的文本文件?该文件可能仅由一个进程的线程访问。

4

3 回答 3

3

文件锁定 API 通常用于进程间锁定。如果您在单个进程中,则Boost.Thread 包中适合您需要的所有内容都可以。应该使用Boost.Interprocess的外部进程。您可能想从 Boost.Interprocess 阅读以下警告:

注意:同步限制

如果您打算像命名互斥锁一样使用文件锁,请小心,因为可移植文件锁具有同步限制,主要是因为不同的实现(POSIX、Windows)提供不同的保证。进程间文件锁有以下限制:

  • 如果 afile_lock同步来自同一进程的两个线程,则未指定。
  • 一个进程是否可以使用file_lock指向同一个文件的两个对象是未指定的。

第一个限制主要来自 POSIX,因为文件句柄是每个进程的属性,而不是每个线程的属性。这意味着如果一个线程使用一个file_lock对象来锁定一个文件,其他线程将看到该文件被锁定。另一方面,Windows 文件锁定机制提供线程同步保证,因此试图锁定已锁定文件的线程会阻塞。

第二个限制来自文件锁定同步状态与 Windows 中的单个文件描述符相关联的事实。这意味着如果创建了两个指向同一个文件的 file_lock 对象,则不能保证同步。在 POSIX 中,当一个描述符被关闭时,当使用两个文件描述符来锁定一个文件时,调用进程设置的所有文件锁都会被清除。

总而言之,如果您打算在进程中使用文件锁定,请使用以下限制:

  • file_lock对于每个文件,每个进程使用一个对象。
  • 使用相同的线程来锁定和解锁文件。
  • 如果您在对该文件使用文件锁的同时使用 std::fstream/native 文件句柄写入文件,请在释放文件的所有锁之前不要关闭该文件。
于 2009-12-02T17:05:16.650 回答
2

我想它是acquire_file_lock

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 
于 2009-01-28T07:54:48.460 回答
1

如果您确定只能从一个进程访问它,那么在线程本地存储中使用文件句柄的读写锁可能是一种解决方案。这将模拟上述情况,只有一个作者,但有几个读者。

于 2009-01-28T07:59:24.427 回答