Обходной путь для многопоточного чтения и записи ncurses - PullRequest
0 голосов
/ 17 декабря 2018

Это то, что написано на http://invisible -island.net / ncurses / ncurses.faq.html # многопоточность

Если у вас есть программа, которая использует проклятия в болеечем один поток, вы почти наверняка увидите странное поведение.Это потому, что curses полагается на статические переменные для ввода и вывода.Использование одного потока для ввода и других для вывода не может решить проблему, а также не могут помочь дополнительные обновления экрана.Этот FAQ не является руководством по многопоточному программированию.

В частности, он упоминает, что это небезопасно, даже если ввод и вывод выполняются в отдельных потоках.Было бы безопасно, если бы мы дополнительно использовали мьютекс для всей библиотеки ncurses, чтобы максимум один поток мог вызывать любую функцию ncurses одновременно?Если нет, то каковы другие дешевые обходные пути для безопасного использования ncurses в многопоточных приложениях?

Я задаю этот вопрос, потому что замечаю, что реальное приложение часто имеет свой собственный цикл обработки событий, но использует ncurses getchфункция, чтобы получить ввод с клавиатуры.Но если основным потоком является ожидание блока в своем собственном цикле событий, у него нет шансов вызвать getch.На первый взгляд приемлемое решение - вызвать getch в другом потоке, что еще не вызвало у меня проблемы, но, как сказано выше, на самом деле небезопасно, и было проверено другим пользователем здесь .Поэтому мне интересно, как лучше всего объединить getch в собственный цикл событий приложения.

Я рассматриваю возможность сделать getch неблокирующим и регулярно пробуждать основной поток (каждые 10-100 мс) проверить, есть ли что почитать.Но это добавляет дополнительную задержку между ключевыми событиями и делает приложение менее отзывчивым.Кроме того, я не уверен, вызовет ли это какие-либо проблемы с некоторой внутренней задержкой ncurses, такой как ESCDELAY.

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

В тексте также упоминаются библиотеки "ncursest" или "ncursestw", но они кажутся менее доступнымиНапример, если вы используете привязку проклятий на другом языке.Было бы здорово, если бы существовало жизнеспособное решение со стандартной библиотекой ncurses.

1 Ответ

0 голосов
/ 27 декабря 2018

Без поддержки потоков вам не повезло, что вы используете функции curses в нескольких потоках.Это потому, что большинство вызовов curses используют статические или глобальные данные.Например, функция getch вызывает refresh, которая может обновлять весь экран, используя глобальные указатели curscr и stdscr.Разница в конфигурации поддержки потоков заключается в том, что глобальные значения преобразуются в функции и добавляются мьютексы.

Если вы хотите прочитать stdin из другого потока и запустить curses в одном потоке вы, вероятно, сможете сделать это, проверив файловый дескриптор (т. е. 0) для ожидающих действий и оповещения потока, который работаетругательства, чтобы сказать это читать данные.

...