read()
и write()
не являются строго поточно-ориентированными, и нет документации, в которой говорится, что они есть, поскольку место, в которое данные считываются или записываются, может быть изменено другим потоком.
За документацию POSIX read
(обратите внимание на выделенные части):
Функция read()
должна попытаться прочитать nbyte
байт из файла, связанного с дескриптором открытого файла, fildes
, в буфер, на который указывает buf
. Поведение нескольких одновременных операций чтения на одном канале, FIFO или терминальном устройстве не определено .
Это та часть, которую вы заметили, но она не охватывает все возможные типы файловых дескрипторов, таких как обычные файлы. Это относится только к «pipe [s], FIFO [s]» и «оконечному устройству [s]». Эта часть охватывает почти все остальное (странные вещи, такие как «файлы» в /proc
, которые генерируются ядром на лету, ну, в общем, странные и сильно зависящие от реализации):
Для файлов, которые поддерживают поиск (например, обычный файл), read()
должен начинаться с позиции в файле, заданной смещением файла, связанным с fildes
. Смещение файла должно увеличиваться на количество фактически прочитанных байтов.
Поскольку «смещение файла, связанное с fildes
» может быть изменено другими потоками в процессе, следующий код не гарантирует возвращение тех же результатов, даже если содержимое файла и входные данные для fd
точно такие же, offset
, buffer
и bytes
:
lseek( fd, offset, SEEK_SET );
read( fd, buffer, bytes );
Поскольку значения read()
и write()
зависят от состояния (смещение текущего файла), которое может быть изменено в любой момент другим потоком, они не являются безопасными для протектора.