LINUX.ORG.RU

Nomacs и MC с MPV друг другу мешают

 , , , ,


1

1

Обнаружил довольно странный баг. Если в MC сменить ассоциированный видеоплеер на Open=mpv %f, запустить из командной строки nomacs path/to/image/file &, затем запустить из MC проигрывание видео, то переключение картинок в Nomacs застрянет через несколько десятков файлов. Причём, если у файлов изображений неверные расширения, застрянет раза в 3 быстрее. При выключении MPV заработает нормально.

Да, это похоже на известную историю про звук в «Star Control 2» :)

Эксперименты показали, что число просмотренных до зависания файлов не зависит от проигрываемого видео и размера изображений. Оно определяется только форматом изображений: 100 WebP, 160 JPEG, 160 PNG, 60 JPEG с неверным расширением. При этом на каждый файл в консоль выводится соответственно 177, 112, 112 и 287 байт. То есть когда MPV монопольно держит консоль, Nomacs виснет после того, как отправит в неё около 18 000 байт текста. И висит, пока MPV консоль не отпустит. Если слать 1 и 2 в /dev/null, баг не проявляется.

Вопросы:

  • Откуда это ограничение в 18 килобайт?
  • Которая из программ себя неправильно ведёт?
★★★★★

Запусти nomacs с strace -o /dev/pts/XXX (где XXX - номер терминала другого окна, можно узнать командой tty, чтобы он свои логи писал туда и не влиял на текущее окно), и посмотри на чём он зависает.

Возможно 18000 байт это размер буфера пайпа или сокета какого-нить, из которого кто-то что-то не забирает вовремя.

При этом на каждый файл в консоль выводится соответственно 177, 112, 112 и 287 байт.

А этот вывод в консоли появляется?

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 2)

похоже на блокировку pipe(stdout/stderr) из-за переполнения буфера, конкретно mpv/nomacs сами по себе тут ни при чём
с неправильным расширением nomacs, вероятно, срёт в stderr активнее

madcore ★★★★★
()
  1. Это размер ядерного буфера для псевдо-терминала.
  2. MC работает как терминальный прокси, связывающий pty «внутри» и pty «снаружи».
  3. Когда ты запускаешь через MC проигрывание в mpv, MC ждёт на waitpid() и больше не выполняет функции прокси.
  4. nomacs расходует весь свой буфер и зависает.

Это рабочая гипотеза.

Насколько это точно, проверю ИИшницей.

wandrien ★★★★
()

Вот полный разбор от ИИ: https://pastebin.com/x2bBnSpT

Ниже - суть кратко. (Сам не проверял.)


Разобрался — и не только по коду, а живым воспроизведением в настоящем терминале (tmux + strace). Полный разбор с доказательствами положил в mc-nomacs-bug/РАЗБОР.md, вот суть.

Что происходит

Дело не в mpv и не в том, что он «занимает консоль». Дело в псевдотерминале, который mc завёл для своей командной строки.

  1. nomacs path/to/file &, запущенный из командной строки mc, — это фоновая задача в pty «сабшелла»: stdin/stdout/stderr смотрят в slave-часть, master держит mc. Единственный читатель этого pty — сам mc: в цикле интерфейса он вычитывает то, что пишут фоновые задачи, и показывает последнюю строку на командной строке.
  2. Когда вы жмёте Enter и срабатывает ассоциация Open=mpv %f, mc выполняет её синхронно, как прямой ребёнок (не через сабшелл): /bin/bash -c … → /bin/sh /tmp/mc-XXXX/mcextXXXX → mpv, и сам mc всё это время стоит в wait4(). Цикла интерфейса нет → pty командной строки никто не читает.
  3. nomacs продолжает строчить по сообщению на каждую картинку в этот pty. Буфер переполняется, и очередная write() встаёт намертво — до тех пор, пока mpv не завершится и mc не вернётся к чтению pty.

В прогоне это видно посимвольно: mc wait4(8795) = 12.3 s (ровно жизнь mpv), у эмулятора nomacs write(1, …112) = 10.6 s и разблокировка через 12 мс после выхода mpv. Причём mpv работает на другом pty — реальном терминале; к pty командной строки он отношения не имеет.

Откуда ~18 КБ

Это ёмкость буфера вывода tty. Запись в tty блокирующая: буфер полон, читателя нет — write() спит. В контролируемом опыте (pty никогда не читают) блокировка наступает после 19457 байт; в живом прогоне в буфер влилось 158 сообщений × 113 Б = 17854 Б, и только потом запись встала.

Числа автора складываются идеально: 100 × 177 = 17 700, 160 × 112 = 17 920, 60 × 287 = 17 220. То есть «100 WebP / 160 JPEG / 60 с неверным расширением» — это просто 18 000 ÷ (байт на файл). Ни число картинок, ни расширение сами по себе не важны — важен байтовый бюджет; поэтому и «не зависит от видео и размера картинок». Redirect в /dev/null убирает записи — копиться нечему — и баг исчезает.

Кто «неправ»

  • mpv — ни при чём (другой pty, о проблеме не знает).
  • mc — действует по своему дизайну, но архитектурная дыра именно здесь: пока mc ждёт внешнюю команду, единственный читатель pty сабшелла не читает его.
  • nomacs — спотыкается первым и ведёт себя наименее удачно: GUI-просмотрщик печатает по строке на каждую картинку в консоль, которой не владеет (mc её вычитывает и молча выбрасывает), да ещё блокирующей записью.

Строго говоря, ни один не нарушает контракт — это штатный backpressure терминала, тот самый класс проблем, что и «звук в Star Control 2». Практика: лечится nomacs файл &>/dev/null &, либо запуском nomacs не из командной строки mc. Кстати, тот же ступор даст любая болтливая фоновая программа в командной строке mc (yes &), а не только nomacs+mpv.

Проверить у себя в момент «ступора»: cat /proc/$(pgrep nomacs)/wchan → wait_woken, cat /proc/$(pgrep mc)/wchan → do_wait.

wandrien ★★★★
()
Ответ на: комментарий от wandrien

Вот объясни, нафига сюда было нести эту простыню слопа, когда весь её смысл в «да, проверил, теория оказалась правильной»? Это выглядит как желание демонстративно показать слоп и не более того.

firkax ★★★★★
()
Ответ на: комментарий от firkax

А я не знаю, правильная она или нет.

Я лично не проверял.

Я показал, что проверила другая система.

Если бы я утверждал, что теория правильная, это было бы эпистемически неверно.

wandrien ★★★★
()
Ответ на: комментарий от question4

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

VIT ★★★
()
Ответ на: комментарий от VIT

а мне в таких случаях думается что если бы я хотел спросить ии, я бы спросил сам. мне интерсно общение с человеком потому что он отвечает за свои слова, а не вываливает на меня ответ в котором не разобрался.

AndreyKl ★★★★★
()
Ответ на: комментарий от AndreyKl

Это как раз аргумент в пользу того, почему не стоит тратить личные усилия на подобные форумные темы.

Тема выглядит как запрос на конструктивный совет/анализ а является способом удовлетворения желания привлечь к себе личное внимание форумчан.

Хорошо, что само наличие ИИ как явления эту дихотомию выявило.

wandrien ★★★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от wandrien

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

[не призываю ни в коем случае отказываться от ИИ, призываю проверять прежде чем писать, поскольку отвественность на авторе а не на инструменте].

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 4)
Ответ на: комментарий от AndreyKl

тогда ИИ отменяет смысл форумов совсем, ибо 99 процентов решается с ИИ.

следовательно, из разделов тут следует оставить только толкс и скриншоты

madcore ★★★★★
()
Ответ на: комментарий от wandrien

madcore

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

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

wandrien

ну или не проверять, а х отя бы перерабатывать ии-шный текст, т.е. ты прочитал его, тебе это кажется верным. ну пиши как есть. вываливать простыню мне кажется неудачным реешнием. но опятьже, моё мнение.

AndreyKl ★★★★★
()
Последнее исправление: AndreyKl (всего исправлений: 2)
Ответ на: комментарий от wandrien

Тема выглядит как запрос на конструктивный совет/анализ а является способом удовлетворения желания привлечь к себе личное внимание форумчан.

Откуда такой вывод? ИИ подсказал? :)

Я хочу занести баги, чтобы прекратить такие глюки. (На Nomacs уже занёс.) Для этого хочу понять, кто из программ неправ и в чём. Спрашивать LLM не хочу, потому что на спорные темы они склонны отвечать так, как приятно спрашивающему.

question4 ★★★★★
() автор топика
Ответ на: комментарий от firkax

При этом на каждый файл в консоль выводится соответственно 177, 112, 112 и 287 байт.

А этот вывод в консоли появляется?

Без MPV при закрытых панелях MC — да. Иначе — не появляются нигде.

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Для этого хочу понять, кто из программ неправ и в чём.

Там нет явным образом неправых. Все 4 участника работают по своей валидной логике: ядро, nomacs, mc и mpv.

Но исправлять в такой ситуации всё равно придётся nomacs - чтобы он не писал ничего в терминал. К счастью, исправить это возможно без перекомпиляции, просто перенаправлением вывода в /dev/null на уровне bash.

В разборе это всё указано уже.

wandrien ★★★★
()
Ответ на: комментарий от wandrien

Но исправлять в такой ситуации всё равно придётся nomacs - чтобы он не писал ничего в терминал.

Авторы на это не пойдут.

А вот почему MC не может в данном случае не блокировать буфер, как он с некоторых пор делает при открытых панелях? В итоге, этот буфер всё равно теряется — но не сразу, а по завершении MPV.

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 1)
Ответ на: комментарий от question4

Авторы на это не пойдут.

o_O У тебя &>/dev/null забанили?

А вот почему MC не может в данном случае не блокировать буфер

Потому что он сидит на waitpid().

wandrien ★★★★
()
Ответ на: комментарий от wandrien

При открытых панелях и работающей в консоли программе MC сталкивается с такой же проблемой и молча сбрасывает буфер. Чем отличается данная ситуация? Почему при проигрывющем видео MPV не открываются панели?

question4 ★★★★★
() автор топика
Ответ на: комментарий от question4

Спрашивать LLM не хочу, потому что на спорные темы они склонны отвечать так, как приятно спрашивающему.

ну эта тема как раз не спорная. Переполнение буфера в mc логами из nomacs - реальный баг как он есть.

Другое дело, что если не знаешь, куда смотреть и в чем дело, то нейронка может потратить тебе хренову тучу токенов, прежде чем докопается до причины. Если вообще докопается.

Lrrr ★★★★★
()
Ответ на: комментарий от question4

Пришлось за компьютер сесть, чтобы ответ написать… Это просто неуважение к моему времени - задавать один и тот же вопрос трижды. Вместо того, чтобы прочитать ИИ где написано то же самое подробно и понятно.

mc создаёт pty.

mc на этом pty запускает subshell.

Всё, что живёт внутри subshell, зависит от того, жив ли mc и обрабатыввает ли он события.

Когда ты запускаешь программу нажатием Enter на файловой панели mc, она запускается НЕ в subshell. Она запускается просто как дочерний процесс mc (fork + exec), и mc делает wait4(), чтобы дождаться, пока дочерний процесс умрёт.

В это время в самом mc ничего не работает. Программы, запущенные через subshell, тоже не работают, если начинают выводить или читать текст через свой pty. Все ждут, когда помрёт твой mpv.

wandrien ★★★★
()
Последнее исправление: wandrien (всего исправлений: 1)
Ответ на: комментарий от AndreyKl

а мне в таких случаях думается что если бы я хотел спросить ии, я бы спросил сам. мне интерсно общение с человеком потому что он отвечает за свои слова, а не вываливает на меня ответ в котором не разобрался.

Это отличный аргумент, слово в слово повторенный несколькими участниками форума. Он вполне заслуживает уважение, но есть одно но.

Вы не первый день на форуме, должны были видеть дискуссию по этому поводу и знать, что явный опрос «как поступать с ИИ и его выводом» не привёл к административным действиям. Как выяснилось, здесь много сторонников обоих точек зрения. Это значит, что в беседе надо учитывать появление вывода ИИ и реагировать так, как будто это ожидаемо. Свою точку зрения на ИИ вывод следует высказывать в соответствующей теме там, где это обсуждают, а не после каждого вывода ИИ. Ваш подход непродуктивный.

VIT ★★★
()
Ответ на: комментарий от wandrien

С какой такой же?

Когда что-то работает в фоне и сыпет в консоль текст. В старых версиях этот текст приводил в беспорядок открытые панели, просмотрщик, редактор или другие программы, работающие поверх. С какого-то момента MC научился подавлять этот вывод при открытых панелях. Никакой остановки, никакого переполнения.

Вместо того, чтобы прочитать ИИ где написано то же самое подробно и понятно.

Прочитал. Ответа нет. Ситуация, когда MC сбрасывает поступающий текст, не рассматривается.

question4 ★★★★★
() автор топика
Последнее исправление: question4 (всего исправлений: 2)
Ответ на: комментарий от question4

Я не знаю, как еще ответить.

Изучите, что такое pty, и как он работает.

Спросите объяснения у ИИ – они хорошо умеют объяснять.

«С какого-то момента MC научился подавлять этот вывод при открытых панелях.» - за одно и вот это прояснится.

wandrien ★★★★
()
Ответ на: комментарий от VIT

Вы не первый день на форуме, должны были видеть дискуссию по этому поводу и знать, что явный опрос «как поступать с ИИ и его выводом» не привёл к административным действиям.

гм-гм, не встречался до сих пор. в целом ок , принято.

AndreyKl ★★★★★
()
Ответ на: комментарий от question4

«subshell» в mc - вечный источник костылей и проблем. Можешь либо сразу назначить виноватой данную сущность (кстати, её можно отключить при компиляции, по крайней мере раньше можно было, и я так и делал), либо пуститься в философские рассуждения о трудностях юниксовых терминалов. Если хочешь закостылить проблему - то дописывай ко всем фоновым командам >> /dev/null 2>&1 < /dev/null. Если исправлять - то исправлять надо, конечно, в mc, способы исправления есть разные, но все они компромиссные. Думаю, расписывать их тут незачем - ты сам лично всё равно это делать не будешь, а авторы mc и так, думаю, про них знают. Один из них, кстати, тут на форуме отделился в форк и делает mc6 (M-Commander) где эта проблема тебе скорее всего не встретится (но, как я уже писал, все фиксы компромиссные, поэтому там появились другие проблемы из-за этого, решай уж сам что тебе больше нравится).

А, ну ладно, есть один способ который точечно исправит конкретно твою проблему: вместо ожидания waitpid либо опрашивать его в цикле, параллельно забирая байты из пайпа фоновой задачи, либо обернуть waitpid в что-то, к чему можно делать select/poll, и ждать его вместе с тем же пайпом. Но это не исправление корня проблем, а только данного симптома.

firkax ★★★★★
()
Последнее исправление: firkax (всего исправлений: 1)
  • Markdown
Пустая строка (два раза Enter) начинает новый абзац. Знак '>' в начале абзаца выделяет абзац курсивом цитирования.
Внимание: прочитайте описание разметки Markdown.
Используйте Ctrl-Enter для размещения комментария