fcntl, lockf, который лучше для использования для захвата файла?

Короткий ответ на ваш вопрос заключается в том, что напечатанное значение основано на типе, который оценивается условным выражением.

Так что действительно ваш вопрос сводится к тому, почему тип условного выражения отличается между

char y = 'y';
int i = 0;
System.out.print(false ? i : y); // prints 121

и

char y = 'y';
System.out.print(false ? 0 : y); // prints y

Чтобы ответить на это, нам нужно взглянуть на раздел §15.25 Спецификации языка Java .

В Java существует три типа условного выражения:

  • Булевы условные выражения
  • Числовые условные выражения
  • Ссылка условно Выражения

Поскольку оба int и char преобразуются в числовой тип, выражение является примером числового условного выражения в соответствии с этим правилом:

Если оба выражения второго и третьего операндов являются числовыми выражениями, условное выражение представляет собой числовое условное выражение.

Для классификации условного выражения следующее выражение s - числовые выражения:

  • Выражение отдельной формы (§15.2) с типом, который преобразуется в числовой тип (§4.2, п. 5.1.8).
blockquote>

Учитывая, что правило для определения типа всего выражения дается следующим образом:

15.25.2. Числовые условные выражения

Числовые условные выражения являются автономными выражениями (§15.2).

Тип числового условного выражения определяется следующим образом:

  • Если второй и третий операнды имеют один и тот же тип, то это тип условного выражения.
  • Если один из второго и третьего операндов имеет примитивный тип T, а тип другого - результат применения преобразования бокса (§5.1.7) в T, то тип условного выражения - T.
  • Если один из операндов имеет тип байта или байт, а другой имеет тип short или Короче говоря, тип условного выражения является коротким.
  • Если один из операндов имеет тип T, где T является байтом, коротким или char, а другой операнд является константным выражением (§15.28) типа int, значение которого представляется в типе T, то тип условного выражения T.
  • Если один из операндов имеет тип T, где T - байт, короткий или символ , а другой операнд является постоянным выражением типа int, значение которого представляется в типе U, являющемся результатом применения преобразования unboxing в T, тогда тип условного выражения U.
  • В противном случае, двоичное числовое продвижение (§5.6.2) применяется к типам операндов, а тип условного выражения - продвинутый тип второго и третьего операндов.

Обратите внимание, что двоичная цифровая продвижение выполняет преобразование набора значений (§5.1.13) и может выполнять преобразование для распаковки (§5.1.8).

blockquote>

Обратите внимание, что четвертое правило точно описывает второй пример; второй операнд является константой типа int (0), а третий является char, поэтому условное выражение будет оцениваться как char. Это заставит компилятор использовать метод print(char), который будет печатать y.

Однако, если вместо переменной вместо константы вы переходите к переменной / g3], вы приходите к последнему правилу, которое гласит, что «... тип условного выражения является продвинутым типом второго и третьего операндов».

Если вы посмотрите на §5.6.2 JLS , он описывает правила продвижения типа следующим образом:

Когда оператор применяет двоичную числовую рекламу к паре операндов, каждый из который должен обозначать значение, которое можно преобразовать в числовой тип, применяются следующие правила, чтобы:

  1. Если какой-либо операнд имеет ссылочный тип, он подвергается распаковке преобразования (§5.1. 8).
  2. Расширение примитивного преобразования (§5.1.2) применяется для преобразования одного или обоих операндов, как определено следующими правилами: Если один из операндов имеет тип double, другой преобразуется в double. В противном случае, если любой из операндов имеет тип float, другой преобразуется в float. В противном случае, если один из операндов имеет тип long, другой преобразуется в long. В противном случае оба операнда преобразуются в тип int.
blockquote>

Следуя этим правилам, тип выражения будет int, поэтому компилятор будет использовать метод print(int), который будет печатать 121 ( значение ascii y).

46
задан cweston 22 February 2009 в 18:01
поделиться

4 ответа

, Что является различием между lockf и fcntl:

Во многих системах, lockf() библиотечная подпрограмма является просто оберткой приблизительно fcntl(). То есть lockf предложения подмножество функциональности, что fcntl делает.

Источник

, Но в некоторых системах, fcntl и lockf блокировки абсолютно независимы.

Источник

, Так как это является зависящим от реализации, удостоверьтесь, что всегда использовали ту же конвенцию. Так или всегда используют lockf от обоих Ваших процессов или всегда используют fcntl. Существует хороший шанс, что они будут взаимозаменяемыми, но более безопасно использовать того же.

то, Какой Вы выбрали, не имеет значения.

<час>

Некоторые примечания по обязательному по сравнению с консультативными блокировками:

Привязывающийся unix/linux значением по умолчанию консультация , означая, что другие процессы не должны следовать правилам блокировки, которые устанавливаются. Таким образом, это не имеет значения, какой путь Вы блокируете, пока Ваши процессы сотрудничества также используют ту же конвенцию.

Linux действительно поддерживает обязательный блокировка, но только если Ваша файловая система смонтирована с опцией на и файлом специальный набор атрибутов. Можно использовать mount -o mand, чтобы смонтировать файловую систему и установить атрибуты файла g-x,g+s, чтобы включить обязательные блокировки, затем использовать fcntl или lockf. Для получения дополнительной информации о как обязательная работа блокировок см. здесь .

Примечание, которое блокировки применяются не к отдельному файлу, но к inode. Это означает, что 2 имен файлов, которые указывают на те же данные файла, совместно используют то же состояние блокировки.

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

<час>

, Как обязательные блокировки работают в Linux:

Относительно обязательных блокировок, если процесс блокирует регион файла с блокировкой чтения, то другим процессам разрешают читать, но не записать в тот регион. Если процесс блокирует регион файла с блокировкой записи, то другим процессам не разрешают читать, ни записать в файл. То, что происходит, когда процессу не разрешают получить доступ к части файла, зависит от того, если Вы указали O_NONBLOCK или нет. Если блокирование будет установлено, то оно будет ожидать для выполнения операции. Если никакое блокирование не будет установлено, то Вы получите код ошибки EAGAIN.

<час>

NFS, предупреждающий:

Быть осторожным, если Вы используете команды блокировки на NFS, монтируются. Поведение не определено, и реализация широко варьируется, использовать ли локальную блокировку только или поддерживать удаленную блокировку.

62
ответ дан Will Vousden 8 November 2019 в 00:09
поделиться

Оба интерфейса являются частью стандарта POSIX, и в наше время оба интерфейса доступны в большинстве систем (я просто проверил Linux, FreeBSD, Mac OS X и Солярис). Поэтому выберите тот, который соответствует лучше Вашим требованиям, и используйте его.

Одно предостережение: это является неуказанным, что происходит, когда один процесс блокирует файл с помощью fcntl и другое использование lockf. В большинстве систем это эквивалентные операции (на самом деле в соответствии с Linux lockf, реализован сверху fcntl), но POSIX говорит, что их взаимодействие является неуказанным. Так, если Вы взаимодействуете с другим процессом, который использует один из двух интерфейсов, выберите того же.

Другие записали, что блокировки являются только консультацией: Вы ответственны за проверку, заблокирован ли регион. Кроме того, не используйте функции stdio, если Вы хотите использовать функциональность блокировки.

10
ответ дан Diomidis Spinellis 8 November 2019 в 00:09
поделиться

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

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

я предполагаю здесь, что файловая система будет локальной - если это не будет, затем все ставки выключены, NFS / другая блокировка дескриптора сетевых файловых систем с различными степенями эффективности (в некоторых случаях ни один)

1
ответ дан MarkR 8 November 2019 в 00:09
поделиться

Ваши основные проблемы, в этом случае (т.е. когда" кодирование демона Linux и удивление, которое лучше подходит использовать для осуществления взаимного исключения "), должны быть:

  1. заблокированный файл будет локален, или это может быть на NFS?
    • , например, пользователь может обмануть Вас в создание и блокировку изодромного с предварением файла Вашего демона на NFS?
  2. , как блокировка будет вести себя, когда fork луг, или когда процесс демона будет завершен с экстремальным предубеждением, например, kill -9?

flock и fcntl команды ведут себя по-другому в обоих случаях.

Моя рекомендация состояла бы в том, чтобы использовать fcntl. Можно обратиться к статья Захвата файла о Википедии для всестороннего обсуждения проблем, связанных с обоими решениями:

у И скопления и fcntl есть причуды, которые иногда озадачивают программистов от других операционных систем. Является ли работа блокировок скопления над сетевыми файловыми системами, такими как NFS, зависящей от реализации. В системах BSD вызовы скопления успешны без операций в секунду. На Linux до 2.6.12 запросов скопления к файлам NFS только действовал бы локально. Ядро 2.6.12 и выше реализации скапливается запросы к файлам NFS с помощью блокировок диапазона байта POSIX. Эти блокировки будут видимы другим клиентам NFS, которые реализуют fcntl () / блокировки POSIX. 1 обновления Блокировки и снижения выпускают старую блокировку прежде, чем применить новую блокировку. Если приложение понизит монопольную блокировку до коллективной блокировки, в то время как другое приложение заблокировано, ожидая монопольной блокировки, последнее приложение получит монопольную блокировку, и первое приложение будет заблокировано. Все блокировки fcntl, связанные с файлом для данного процесса, удалены, когда любой дескриптор файла для того файла закрывается тем процессом, даже если блокировку никогда не требовали на тот дескриптор файла. Кроме того, fcntl блокировки не наследованы дочерним процессом. Близкая семантика fcntl особенно неприятна для приложений, которые называют библиотеки подпрограмм, которые могут получить доступ к файлам.

9
ответ дан strager 8 November 2019 в 00:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: