Как зайти в Даркнет?!
25th January, 01:11
6
0
Как в tkinter из поля ввода Entry получить значение в одну переменную и обновить строку кнопкой, затем получить ещё одно введённое значение и затем сложить их. Ниже пример кода
21st July, 19:00
895
0
Программа, которая создает фейковые сервера в поиске игровых серверов CS 1.6 Steam
21st March, 17:43
948
0
Очень долго работает Update запрос Oracle
27th January, 09:58
914
0
не могу запустить сервер на tomcat HTTP Status 404 – Not Found
21st January, 18:02
905
0
Где можно найти фрилансера для выполнения поступающих задач, на постоянной основе?
2nd December, 09:48
938
0
Разработка мобильной кроссплатформенной военной игры
16th July, 17:57
1724
0
период по дням
25th October, 10:44
3955
0
Пишу скрипты для BAS только на запросах
16th September, 02:42
3720
0
Некорректный скрипт для закрытия блока
14th April, 18:33
4613
0
прокидывать exception в блоках try-catch JAVA
11th March, 21:11
4381
0
Помогите пожалуйста решить задачи
24th November, 23:53
6086
0
Не понимаю почему не открывается детальное описание продукта
11th November, 11:51
4351
0
Нужно решить задачу по программированию на массивы
27th October, 18:01
4396
0
Метода Крамера С++
23rd October, 11:55
4309
0
помогите решить задачу на C++
22nd October, 17:31
4002
0
Помогите решить задачу на python с codeforces
22nd October, 11:11
4492
0
Python с нуля: полное руководство для начинающих
18th June, 13:58
2599
0
Bash Обработка Труб
Кто-нибудь знает, как bash обрабатывает отправку данных по каналам?
cat file.txt | tail -20
Выводит ли эта команда все содержимое file.txt в буфер, который затем считывается tail? Или эта команда, скажем, выводит содержимое file.txt строка за строкой, а затем делает паузу в каждой строке для обработки хвоста, а затем запрашивает дополнительные данные?
Причина, по которой я спрашиваю, заключается в том, что я пишу программу на встроенном устройстве, которое в основном выполняет последовательность операций с некоторым куском данных, где выход одной операции отсылается в качестве входа следующей операции. Я хотел бы знать, как linux (bash) справляется с этим, поэтому, пожалуйста, дайте мне общий ответ, а не конкретно, что происходит, когда я запускаю "cat file.txt | tail -20".
Заранее благодарим вас за ваши ответы!
EDIT: Shog9 указал на соответствующую статью Википедии, это не привело меня непосредственно к статье, но это помогло мне найти это: http://en.wikipedia.org/wiki/Pipeline_% 28Unix%29#реализация , которая действительно имела информацию, которую я искал.
Мне очень жаль, что я не совсем ясно выразился. Конечно, вы используете канал и, конечно же, используете stdin и stdout соответствующих частей команды. Я предполагал, что это было слишком очевидно, чтобы утверждать.
Я спрашиваю, как это handled/implemented., так как обе программы не могут работать одновременно, как данные передаются из stdin в stdout? Что произойдет, если первая программа генерирует данные значительно быстрее, чем вторая программа? Выполняет ли система просто первую команду до тех пор, пока она не завершится или не заполнится буфер stdout, а затем переходит к следующей программе и так далее в цикле, пока не останется больше данных для обработки, или есть более сложный механизм?
Я решил написать чуть более подробное объяснение.
"magic" здесь лежит в операционной системе. Обе программы запускаются примерно в одно и то же время и выполняются в одно и то же время (операционная система назначает им отрезки времени на процессоре для запуска), как и любой другой одновременно запущенный процесс на вашем компьютере (включая приложение terminal и kernel). Таким образом, прежде чем какие-либо данные будут переданы, процессы выполняют любую необходимую инициализацию. В вашем примере tail анализирует аргумент '-20', а cat анализирует аргумент' file.txt ' и открывает файл. В какой-то момент tail доберется до точки, где ему нужен вход, и он сообщит операционной системе, что он ждет ввода. В какой-то другой момент (до или после, неважно) cat начнет передавать данные в операционную систему с помощью stdout. Это идет в буфер в операционной системе. В следующий раз, когда tail получает временной срез на процессоре после того, как некоторые данные были помещены в буфер cat, он будет извлекать некоторое количество этих данных (или все это), которое оставляет буфер в операционной системе. Когда буфер пуст, в какой-то момент tail придется ждать, пока cat выведет больше данных. Если cat выводит данные намного быстрее, чем tail обрабатывает их, буфер будет расширяться. cat в конечном итоге будет делать вывод данных, но хвост все равно будет обрабатывать, поэтому cat закроется, а хвост будет обрабатывать все оставшиеся данные в буфере. Операционная система будет сигнализировать хвост, когда их больше нет входящих данных с EOF. Хвост будет обрабатывать оставшиеся данные. В этом случае tail, вероятно, просто получает все данные в циклический буфер из 20 строк, и когда операционная система сигнализирует, что больше нет входящих данных, он затем сбрасывает последние двадцать строк в свой собственный stdout, который просто отображается в terminal. Поскольку tail-это гораздо более простая программа, чем cat, она, скорее всего, проведет большую часть времени, ожидая, пока cat поместит данные в буфер.
В системе с несколькими процессорами эти две программы будут не просто совместно использовать чередующиеся временные срезы на одном процессорном ядре, но, скорее всего, работать одновременно на разных ядрах.
Если вы откроете какой-нибудь монитор процессов (специфичный для операционной системы), например 'top' в Linux, вы увидите целый список запущенных процессов, большинство из которых эффективно используют 0% процессора. Большинство приложений, если только они не уничтожают данные, проводят большую часть своего времени, ничего не делая. Это хорошо, потому что позволяет другим процессам иметь неограниченный доступ к процессору в соответствии с их потребностями. Это достигается в основном тремя способами. Процесс может перейти к инструкции типа sleep (n), где он в основном говорит kernel подождать n миллисекунд, прежде чем дать ему другой временной срез для работы. Чаще всего программе приходится ждать чего-то от другой программы, например 'tail', ожидая, пока в буфер поступит больше данных. В этом случае операционная система будет пробуждать процесс, когда будет доступно больше данных. Наконец, kernel может опережать процесс в середине выполнения, предоставляя некоторые фрагменты процессорного времени другим процессам. 'cat' и 'tail'-это простые программы. В этом примере tail тратит большую часть своего времени на ожидание дополнительных данных в буфере, а cat тратит большую часть своего времени на ожидание операционной системы для получения данных с жесткого диска. Узким местом является скорость (или медлительность) физического носителя, на котором хранится файл. Эта заметная задержка, которую вы можете обнаружить при первом запуске этой команды, - это время, необходимое для того, чтобы головки считывания на жестком диске искали позицию на жестком диске, где находится 'file.txt'. Если вы выполните команду во второй раз, операционная система, скорее всего, будет иметь содержимое file.txt, кэшированное в памяти, и вы, скорее всего, не увидите никакой заметной задержки (если только file.txt не очень большой или файл больше не кэшируется.)
Большинство операций, выполняемых на вашем компьютере, связаны с IO, то есть вы обычно ожидаете поступления данных с жесткого диска или сетевого устройства и т. д.
Shog9 уже ссылался на статью Википедии, но в разделе реализации есть нужные вам детали. Основная реализация - это ограниченный буфер.