Может канал в Linux когда-нибудь терять данные?

И есть ли верхний предел того, сколько данных он может содержать?

14
задан codeforester 19 May 2017 в 19:00
поделиться

4 ответа

Запрет сбоя машины, нет, он не может потерять данные. Однако его легко использовать неправильно и подумать, что вы теряете данные, либо потому, что при записи не удалось записать все запрошенные данные, и вы не проверили возвращаемое значение, либо вы сделали что-то не так с чтением.

Максимальный объем данных, который он может содержать, зависит от системы - если вы попытаетесь записать больше, вы либо получите короткую запись, либо писатель заблокируется, пока не освободится место. Справочная страница pipe (7) содержит много полезной информации о каналах, включая (по крайней мере, в Linux) размер буфера.В Linux есть буферы размером 4 КБ или 64 КБ в зависимости от версии.

править

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

PIPE_BUF - это константа, которая сообщает вам предел атомарных записей в буфер. Любая запись этого размера или меньше будет либо завершена успешно, либо будет заблокирована до тех пор, пока не будет завершена полностью (или предоставит EWOULDBLOCK / EAGAIN, если канал находится в неблокирующем режиме). Это не имеет никакого отношения к фактическому размеру буфера канала ядра, хотя очевидно, что размер буфера должен быть не менее PIPE_BUF, чтобы соответствовать гарантии атомарности.

21
ответ дан 1 December 2019 в 09:12
поделиться

Ваша труба не теряет данные. Если вы теряете данные в своем приложении, попробуйте отладить его с помощью gdb. Пара вещей, на которые следует обратить внимание:
1) Достаточно ли велик ваш буфер для хранения всех данных, которые ты читаешь?
2) Проверьте коды возврата из функции read () в конвейере на наличие ошибок.
3) Вы уверены, что записываете все данные в канал?
4) Ваша операция записи / чтения прерывается сигналом? например: SIGPIPE?

2
ответ дан 1 December 2019 в 09:12
поделиться

Если вы имеете в виду использование оператора | в оболочке, то нет, он не потеряет данные. Он просто подключает приложение в стандартном потоке вывода на левой стороне к приложению в стандартном потоке ввода справа. Если вы передаете данные между приложениями и не получаете ожидаемых результатов, попробуйте использовать > для перенаправления стандартного вывода из первого приложения в файл, а затем используйте <, чтобы использовать это файл в качестве стандартного ввода для второго приложения. Таким образом, вы можете проверить файл и убедиться, что данные отправляются в ожидаемом вами формате.

Если вы имеете в виду канал, созданный функцией pipe , то ответ все равно отрицательный. Согласно на этой странице руководства , запись в полный канал будет блокироваться до тех пор, пока не будет прочитано достаточно данных, чтобы освободить место для данных записи. В нем также указано, что размер канала составляет 4 КБ в Linux до версии 2.6.11 и 64 КБ в версии 2.6.11 и новее.

2
ответ дан 1 December 2019 в 09:12
поделиться

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

1
ответ дан 1 December 2019 в 09:12
поделиться
Другие вопросы по тегам:

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