Что является аналогом для блокировки файлов win32 в boost :: interprocess? - PullRequest
2 голосов
/ 28 января 2009

Какой механизм синхронизации я должен использовать для предоставления эксклюзивного доступа к текстовому файлу в Boost? Файл, вероятно, будет доступен для потоков только из одного процесса.

Ответы [ 3 ]

3 голосов
/ 02 декабря 2009

API блокировки файлов, как правило, предназначены для межпроцессной блокировки. Если вы находитесь в одном процессе, все в Boost.Thread пакете , которое соответствует вашим потребностям, подойдет. Внешние процессы должны использоваться Boost.Interprocess . Возможно, вы захотите прочитать следующее предупреждение от Boost.Interprocess:

Caution: Synchronization limitations

Если вы планируете использовать блокировки файлов точно так же, как и именованные мьютексы, будьте осторожны, потому что переносимые блокировки файлов имеют ограничения синхронизации, главным образом потому, что разные реализации (POSIX, Windows) предлагают разные гарантии. Межпроцессные блокировки файлов имеют следующие ограничения:

  • Не указано, если file_lock синхронизирует два потока из одного процесса.
  • Не определено, может ли процесс использовать два объекта file_lock, указывающих на один и тот же файл.

Первое ограничение в основном исходит от POSIX, поскольку дескриптор файла является атрибутом для процесса, а не атрибутом для потока. Это означает, что если поток использует объект file_lock для блокировки файла, другие потоки увидят файл как заблокированный. Механизм блокировки файлов Windows, с другой стороны, предлагает гарантии синхронизации потоков, поэтому поток, пытающийся заблокировать уже заблокированный файл, заблокируется.

Второе ограничение связано с тем, что в Windows состояние синхронизации блокировки файлов связано с одним дескриптором файла. Это означает, что если создаются два объекта file_lock, указывающие на один и тот же файл, синхронизация не гарантируется. В POSIX, когда два файловых дескриптора используются для блокировки файла, если дескриптор закрыт, все блокировки файлов, установленные вызывающим процессом, очищаются.

Подводя итог, если вы планируете использовать блокировку файлов в своих процессах, используйте следующие ограничения:

  • Для каждого файла используйте один file_lock объект на процесс.
  • Используйте один и тот же поток для блокировки и разблокировки файла.
  • Если вы используете дескриптор файла std :: fstream / native для записи в файл при использовании блокировок файла для этого файла, не закрывайте файл до снятия всех блокировок файла.
2 голосов
/ 28 января 2009

Полагаю, это acqu_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);
}

Это согласуется с реализацией блокировки без усиления .

    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 
1 голос
/ 28 января 2009

Если вы уверены, что к нему будет доступ только из одного процесса, решением проблемы может стать блокировка чтения-записи с файловыми дескрипторами в локальном хранилище потока. Это имитирует вышесказанное только с одним писателем, но несколькими читателями.

...