Есть ли официальный документ, который помечает функцию чтения / записи как поточно-ориентированные функции? - PullRequest
1 голос
/ 02 мая 2019

на страницах справки для чтения / записи ничего не сказано о безопасности потоков

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

В другой руке по этой ссылке ! который говорит:

The read() function shall attempt to read nbyte bytes
from the file associated with the open file descriptor,
fildes, into the buffer pointed to by buf.
The behavior of multiple concurrent reads on the same pipe, FIFO, or 
terminal device is unspecified.

Я пришел к выводу, что функция чтения не является поточно-ориентированной.

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

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

спасибо заранее:)

Ответы [ 3 ]

2 голосов
/ 02 мая 2019

Потоково-безопасными версиями read и write являются pread и pwrite:

pread (2)

   The pread() and pwrite() system calls are especially useful in
   multithreaded applications.  They allow multiple threads to perform
   I/O on the same file descriptor without being affected by changes to
   the file offset by other threads.

придва потока write () одновременно не указан порядок (который сначала выполняет вызов write), поэтому поведение не определено (без синхронизации)

1 голос
/ 02 мая 2019

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() зависят от состояния (смещение текущего файла), которое может быть изменено в любой момент другим потоком, они не являются безопасными для протектора.

0 голосов
/ 02 мая 2019

В некоторых встроенных файловых системах или действительно старых настольных системах, не предназначенных для поддержки поддержки многозадачности (например, MS-DOS 3.0), попытка выполнить fread() для одного файла во время выполнения fread() в другом файле может привести к произвольному повреждению системы.

Любая современная операционная система и языковая среда выполнения гарантируют, что такое повреждение не произойдет в результате операций, выполняемых над несвязанными файлами, или когда независимые файловые дескрипторы используются для доступа к одному и тому же файлу способами, которые не изменяют его. Такие функции, как fread() и fwrite() будут поточно-ориентированными при использовании таким образом .

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

...