问题描述
我正在尝试编写将屏幕分为两个窗口,其中一个窗口由另一个线程修改的代码,但是输出似乎非常随机.有人可以帮忙吗?控制台的上半部分应由main修改,而下层则应由线程k
修改.
I'm trying to write code where the screen is divided into two windows and one of them is modified by a different thread, but output seems to be very random. Could anyone help? Upper piece of console should be modified by main, and lower by thread k
.
#include <stdio.h>
#include <ncurses.h>
#include <unistd.h>
#include <thread>
#define WIDTH 30
#define HEIGHT 10
int startx = 0;
int starty = 0;
void kupa (int score_size, int parent_x, int parent_y)
{
int i = 0;
WINDOW *dupa = newwin(score_size, parent_x, parent_y - score_size, 0);
while(true)
{
i++;
mvwprintw(dupa, 0 , 0, "You chose choice %d with choice string", i);
wrefresh(dupa);
sleep(5);
wclear(dupa);
}
delwin(dupa);
}
int main ()
{
int parent_x, parent_y;
int score_size =10;
int counter =0 ;
initscr();
noecho();
curs_set(FALSE);
getmaxyx(stdscr, parent_y, parent_x);
WINDOW *field = newwin(parent_y - score_size, parent_x, 0, 0);
std::thread k (kupa, score_size, parent_x, parent_y);
while(true) {
mvwprintw(field, 0, counter, "Field");
wrefresh(field);
sleep(5);
wclear(field);
counter++;
}
k.join();
delwin(field);
}
推荐答案
基础curses/ncurses库不是线程安全的(例如,请参见,该词讨论了该术语).在出现诅咒的情况下,这意味着库的WINDOW
结构(例如stdscr
)是不受互斥量或其他方法保护的全局变量.该库还具有内部 static 数据,这些数据在Windows之间共享.使用以下策略之一,您只能获得多线程代码的可靠结果:
The underlying curses/ncurses library is not thread-safe (see for example What is meant by "thread-safe" code? which discusses the term). In the case of curses, this means that the library's WINDOW
structures such as stdscr
are global variables which are not guarded by mutexes or other methods. The library also has internal static data which is shared across windows. You can only get reliable results for multithreaded code using one of these strategies:
- 在一个线程内
- 执行窗口管理(包括输入)的所有操作
- 使用互斥量,信号量或其他并发性技术似乎最好单独管理拥有"单独窗口的线程.要在这里成功,线程必须在等待输入时从curses库阻塞的位置开始拥有整个屏幕,直到它更新屏幕并恢复等待输入为止.那比听起来难.
- do all of the window management (including input) within one thread
- use mutexes, semaphores or whatever concurrency technique seems best to manage separate threads which "own" separate windows. To succeed here, a thread would have to own the whole screen from the point where the curses library blocks while waiting for input, until it updates the screen and resumes waiting for input. That is harder than it sounds.
ncurses 5.7 及更高版本可以编译为可重入代码和某些线程化应用程序提供基本支持.为此,它使用包裹在其静态数据周围的互斥体,使全局变量成为"getter"函数,并添加显式传递许多调用中暗含的SCREEN
指针的函数.有关更多详细信息,请参见手册页.
ncurses 5.7 and up can be compiled to provide rudimentary support for reentrant code and some threaded applications. To do this, it uses mutexes wrapped around its static data, makes the global variables into "getter" functions, and adds functions which explicitly pass the SCREEN
pointer which is implied in many calls. For more detail, see the manual page.
ncurses的某些测试程序说明了线程支持(这些程序位于源代码的test
子目录中):
Some of ncurses' test-programs illustrate the threading support (these are programs in the test
subdirectory of the sources):
- 同上显示
use_screen
. - test_opaque执行
WINDOW
属性的获取器" - 雨后秀
use_window
- 蠕虫显示
use_window
- ditto shows
use_screen
. - test_opaque execises the "getters" for
WINDOW
properties - rain shows
use_window
- worm shows
use_window
这篇关于两个Windows-一个由线程随机输出修改的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!