总体问题很简单:
如何在多线程 ncurses 程序中优雅地调整窗口大小?
详细信息请参见此处。我读过一些相关问题(1,2,3)。根据我的理解,基本上有两种方法来处理窗口大小调整:
endwin
在refresh
用户自己的处理程序中调用SIGWINCH
。利用 ncurses 内置
SIGWINCH
处理程序:getch
aKEY_RESIZE
并处理它。
我已经测试了我的 ncurses 实现,以确保我可以接收KEY_RESIZE
.但我仍然不明白信号处理程序如何与多线程 ncurses 程序一起工作:
如果我使用内置
SIGWINCH
处理程序,哪个线程将运行信号处理程序?这有关系吗?我可以控制这个吗?内置
SIGWINCH
处理程序生成一个KEY_RESIZE
.但是,如果按下了其他尚未送达的键怎么办?保证是KEY_RESIZE
下次调用返回的密钥吗getch
?处理
KEY_RESIZE
看起来比编写我自己的SIGWINCH
处理程序更轻松。但如何才能在密钥送达后立即读取该密钥以使 UI 做出响应呢?我可以选择或轮询标准输入来检测其传送吗?它是否被放在一个只与stdin有关getch
但与stdin无关的内部队列中?如果我正在编写自己的
SIGWINCH
处理程序,我是否对 ncurses 上下文有任何保证,以便我的信号处理程序代码不会破坏 ncurses(通过调用在传递信号时无法调用的函数等)?ncurses本身是单线程还是多线程?如果我阻止
SIGWINCH
除主线程之外的所有线程上的信号,我是否能保证SIGWINCH
在主线程上接收到信号(但不是由 ncurses 库创建的内部线程)?
答案1
这是几个问题。简要地:
ncurses 是单线程的。
恩诅咒可以配置(构建时)以提高其可重入性并添加一些函数来简化在其结构上使用互斥体。但大多数打包者不使用该功能。一些 ncurses 示例程序演示了该功能。
大多数 Curses 实现(即 35 年以上的任何新版本)都允许您
wgetch
以非阻塞方式或非常短的超时进行调用。除非您使用的 ncurses 配置具有(基本!)对线程应用程序的支持(并且在它是限制),所有 ncurses 输入/输出都应该在单个线程上。你的其他线程可以做他们想做的事。
ncurses 使用静态(持久/全局)变量来记录信号到达。这可能消除了信号到达与设置处理程序的线程不同的线程的潜在问题。但正如建议的那样这里,您可能会发现一个错误。