ncurses多线程读写解决方法
Workaround for ncurses multi-thread read and write
http://invisible-island.net/ncurses/ncurses.faq.html#multithread
上是这么说的
If you have a program which uses curses in more than one thread, you will almost certainly see odd behavior. That is because curses relies upon static variables for both input and output. Using one thread for input and other(s) for output cannot solve the problem, nor can extra screen updates help. This FAQ is not a tutorial on threaded programming.
具体来说,它提到即使输入和输出在不同的线程上完成也是不安全的。如果我们进一步对整个 ncurses 库使用互斥锁,以便一次最多一个线程可以调用任何 ncurses 函数,是否安全?如果不是,在多线程应用程序中安全使用 ncurses 的其他廉价解决方法是什么?
我问这个问题是因为我注意到一个真实的应用程序通常有自己的事件循环但依赖于 ncurses getch
函数来获取键盘输入。但是如果主线程在自己的事件循环中阻塞等待,那么它就没有机会调用getch
。一个看似可行的解决方案是在不同的线程中调用getch
,这还没有给我带来问题,但正如上面所说的实际上是不安全的,并被另一个用户验证here。所以我想知道将 getch
合并到应用程序自己的事件循环中的最佳方法是什么。
我正在考虑使 getch
非阻塞并定期(每 10-100 毫秒)唤醒主线程以检查是否有可读取的内容。但这会在关键事件之间增加额外的延迟,并降低应用程序的响应速度。另外,我不确定这是否会导致某些 ncurses 内部延迟出现问题,例如 ESCDELAY
.
我正在考虑的另一个解决方案是直接轮询标准输入。但我想 ncurses 也应该做类似的事情,从两个不同的地方读取同一个流看起来很糟糕。
文中还提到了 "ncursest" 或 "ncursestw" 库,但它们似乎不太可用,例如,如果您使用不同语言的 curses 绑定。如果标准 ncurses 库有可行的解决方案,那就太好了。
如果没有线程支持,您将无法在多个线程中使用 curses 函数。那是因为大多数 curses 调用使用静态或全局数据。 getch
函数调用 refresh
可以更新整个屏幕——使用全局指针 curscr
和 stdscr
。线程支持配置的不同之处在于全局值被转换为函数并添加了互斥量。
如果你想从另一个线程读取 stdin 并在一个线程中读取 运行 curses,你可能可以通过检查 文件描述符 (即 0
)等待 activity 并警告 运行 诅咒的线程告诉它读取数据。
http://invisible-island.net/ncurses/ncurses.faq.html#multithread
上是这么说的If you have a program which uses curses in more than one thread, you will almost certainly see odd behavior. That is because curses relies upon static variables for both input and output. Using one thread for input and other(s) for output cannot solve the problem, nor can extra screen updates help. This FAQ is not a tutorial on threaded programming.
具体来说,它提到即使输入和输出在不同的线程上完成也是不安全的。如果我们进一步对整个 ncurses 库使用互斥锁,以便一次最多一个线程可以调用任何 ncurses 函数,是否安全?如果不是,在多线程应用程序中安全使用 ncurses 的其他廉价解决方法是什么?
我问这个问题是因为我注意到一个真实的应用程序通常有自己的事件循环但依赖于 ncurses getch
函数来获取键盘输入。但是如果主线程在自己的事件循环中阻塞等待,那么它就没有机会调用getch
。一个看似可行的解决方案是在不同的线程中调用getch
,这还没有给我带来问题,但正如上面所说的实际上是不安全的,并被另一个用户验证here。所以我想知道将 getch
合并到应用程序自己的事件循环中的最佳方法是什么。
我正在考虑使 getch
非阻塞并定期(每 10-100 毫秒)唤醒主线程以检查是否有可读取的内容。但这会在关键事件之间增加额外的延迟,并降低应用程序的响应速度。另外,我不确定这是否会导致某些 ncurses 内部延迟出现问题,例如 ESCDELAY
.
我正在考虑的另一个解决方案是直接轮询标准输入。但我想 ncurses 也应该做类似的事情,从两个不同的地方读取同一个流看起来很糟糕。
文中还提到了 "ncursest" 或 "ncursestw" 库,但它们似乎不太可用,例如,如果您使用不同语言的 curses 绑定。如果标准 ncurses 库有可行的解决方案,那就太好了。
如果没有线程支持,您将无法在多个线程中使用 curses 函数。那是因为大多数 curses 调用使用静态或全局数据。 getch
函数调用 refresh
可以更新整个屏幕——使用全局指针 curscr
和 stdscr
。线程支持配置的不同之处在于全局值被转换为函数并添加了互斥量。
如果你想从另一个线程读取 stdin 并在一个线程中读取 运行 curses,你可能可以通过检查 文件描述符 (即 0
)等待 activity 并警告 运行 诅咒的线程告诉它读取数据。