Почему fnctl никогда не возвращает ошибку при попытке разблокировать файл? - PullRequest
0 голосов
/ 15 апреля 2011

Я написал простую программу, помогающую мне проверить блокировку файла fcntl. Аргумент 'set' блокирует мой тестовый файл. Аргумент 'get' говорит мне, заблокирован ли файл или нет. Аргумент 'un' пытается разблокировать файл.

В одной оболочке я запускаю программу для блокировки файла. Я держу файл открытым и жду ввода.

$ ./lock set
file is locked
hit enter to release lock with a call to fcntl

В другой оболочке я запускаю программу для блокировки файла. Это не работает, потому что файл уже заблокирован. Я запускаю программу, чтобы проверить блокировку. Мне сказали, что замок недоступен. Все это работает как положено.

$ ./lock get
locking is not possible
$ ./lock set
locking file failed

Что произойдет, если я попытаюсь разблокировать мой файл во второй оболочке? Кажется, fcntl никогда не возвращает мне ошибку при вызове с l_type = F_UNLCK.

$ ./lock un
unlocked
file either was successfully unlocked or was already unlocked
$ ./lock get
locking is not possible
$ ./lock set
locking file failed

Я знаю, что мой код разблокировки хорош. Если я вернусь в оболочку один и позволю программе разблокировать:

$ ./lock set
file is locked
hit enter to release lock with a call to fcntl

unlocked
hit enter to close the file

Я могу подтвердить результат во второй оболочке:

$ ./lock get
locking is possible

Я использую только эксклюзивную блокировку записи для всего файла:

  fl.l_type = F_WRLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;
  fl.l_pid = -1; // used by F_GETLK only

  result = fcntl(fd, F_SETLK, &fl);

Вот как я делаю разблокировку:

  fl.l_type = F_UNLCK;
  fl.l_whence = SEEK_SET;
  fl.l_start = 0;
  fl.l_len = 0;
  fl.l_pid = -1; // used by F_GETLK only

  result = fcntl(fd, F_SETLK, &fl);
  if (!result)
  {
    printf("unlocked\n");
  }

Я работаю над RHEL 5.5.

Можете ли вы объяснить это поведение fcntl? Спасибо!

EDIT. Похоже, что из справочной страницы подразумевается, что операция разблокировки предназначена только для владельца блокировки: «Помимо удаления явным образом F_UNLCK, блокировки записи автоматически снимаются, когда процесс завершается или закрывается любой дескриптор файла, ссылающийся на файл, для которого удерживаются блокировки. "

Ответы [ 2 ]

0 голосов
/ 15 апреля 2011

Более того, именно это и определяет POSIX. Это далеко не единственное или даже самое сомнительное решение, которое они приняли в отношении блокировок файлов (последнее будет означать, что все системные блокировки для данного файла должны быть сняты, когда любой процесс с файловым дескриптором, открытым для файла close() s это).

0 голосов
/ 15 апреля 2011

Потому что ... это так работает?

В системах Unix блокировки рекомендуются. Вы используете их, пытаясь получить блокировку, и только делая то, что вы хотите, если вам это удастся.

Сюда входит разблокировка файла. Поскольку вся система является добровольной, ничто не мешает вам разблокировать файл из другого процесса, и поэтому ваша программа всегда преуспевает в этом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...