"все" и "любой" хороши для многих условий того же случая типа. НО они всегда оценивают все условия. Как показано в этом примере:
def c1():
print " Executed c1"
return False
def c2():
print " Executed c2"
return False
print "simple and (aborts early!)"
if c1() and c2():
pass
print
print "all (executes all :( )"
if all((c1(),c2())):
pass
print
До стандартизации существовали ioctl (
... FIONBIO
... )
и fcntl (
... O_NDELAY
... )
, но они вели себя непоследовательно между системами и даже внутри одной системы. Например, FIONBIO
было обычным делом для работы с сокетами, а O_NDELAY
для работы с ttys, с большой несогласованностью для таких вещей, как каналы, FIFO и устройства. И если вы не знаете, какой у вас файловый дескриптор, вам придется установить оба, чтобы быть уверенным. Но кроме того, неблокирующее чтение при отсутствии данных также указывалось непоследовательно; в зависимости от ОС и типа файлового дескриптора при чтении может возвращаться 0 или -1 с ошибкой EAGAIN или -1 с ошибкой EWOULDBLOCK. Даже сегодня, установка FIONBIO
или O_NDELAY
в Solaris приводит к тому, что чтение без данных возвращает 0 на tty или конвейере или -1 с ошибкой EAGAIN на сокете. Однако значение 0 является неоднозначным, поскольку оно также возвращается для EOF.
POSIX решил эту проблему с введением O_NONBLOCK
, который имеет стандартизованное поведение для различных систем и типов файловых дескрипторов. Поскольку существующие системы обычно хотят избежать каких-либо изменений в поведении, которые могут нарушить обратную совместимость, POSIX определил новый флаг, а не предписывал конкретное поведение для одного из других. Некоторые системы, такие как Linux, обрабатывают все 3 одинаково, а также определяют EAGAIN и EWOULDBLOCK с одним и тем же значением, но системы, желающие сохранить какое-либо другое устаревшее поведение для обратной совместимости, могут сделать это при использовании старых механизмов.
Как сказал @Sean, fcntl ()
в значительной степени стандартизирован и поэтому доступен на всех платформах. Функция ioctl ()
предшествовала fcntl ()
в Unix, но совсем не стандартизирована. То, что ioctl ()
работал для вас на всех релевантных для вас платформах, это удача, но не гарантируется. В частности, имена, используемые для второго аргумента, непонятны и ненадежны для разных платформ. Действительно, они часто уникальны для конкретного драйвера устройства, на который ссылается файловый дескриптор. (Вызовы ioctl ()
, используемые для устройства с побитовой графикой, работающего на ICL Perq под управлением PNX (Perq Unix) двадцатилетней давности, никогда не переводились, например, ни на что другое).
Я считаю, что fcntl ()
- это функция POSIX. Где ioctl ()
- это стандартная вещь UNIX. Вот список POSIX io . ioctl ()
очень специфичен для ядра / драйвера / ОС, но я уверен, что то, что вы используете, работает в большинстве разновидностей Unix. некоторые другие ioctl ()
вещи могут работать только на определенных ОС или даже на определенных версиях ядра.