两个 Windows - 一个被线程随机输出修改
Two Windows - one modified by thread random output
我正在尝试编写将屏幕分成两部分的代码 windows,其中之一由不同的线程修改,但输出似乎非常随机。有人能帮忙吗?控制台的上半部分应该由 main 修改,下半部分由线程 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);
}
我不确定你想做什么,但这种行为很正常。活动线程写入 window,当系统进行任务切换时,另一个线程写入 window。正常行为是仅使用一个写入 window 的线程。其他线程应该只做一些工作。
无论如何,如果您使用多个线程,则必须使用事件、互斥锁、队列、信号量或其他方法来同步它们。
底层的 curses/ncurses 库不是线程安全的(例如 What is meant by “thread-safe” code? 讨论了该术语)。在 curses 的情况下,这意味着库的 WINDOW
结构,例如 stdscr
是不受互斥锁或其他方法保护的全局变量。该库还具有内部 static 数据,这些数据在 windows 之间共享。您只能使用以下策略之一获得多线程代码的可靠结果:
- 在一个线程内完成所有的window管理(包括输入)
- 使用互斥锁、信号量或任何 concurrency 技术似乎最好地管理单独的线程,这些线程 "own" 分开 windows。要在这里取得成功,一个线程必须拥有整个屏幕,从 curses 库 blocks 等待输入时开始,直到它更新屏幕并恢复等待输入。这比听起来更难。
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
子目录中):
- 同上显示
use_screen
。
- test_opaque 为
WINDOW
属性执行 "getters"
- 下雨
use_window
- 蠕虫显示
use_window
我正在尝试编写将屏幕分成两部分的代码 windows,其中之一由不同的线程修改,但输出似乎非常随机。有人能帮忙吗?控制台的上半部分应该由 main 修改,下半部分由线程 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);
}
我不确定你想做什么,但这种行为很正常。活动线程写入 window,当系统进行任务切换时,另一个线程写入 window。正常行为是仅使用一个写入 window 的线程。其他线程应该只做一些工作。 无论如何,如果您使用多个线程,则必须使用事件、互斥锁、队列、信号量或其他方法来同步它们。
底层的 curses/ncurses 库不是线程安全的(例如 What is meant by “thread-safe” code? 讨论了该术语)。在 curses 的情况下,这意味着库的 WINDOW
结构,例如 stdscr
是不受互斥锁或其他方法保护的全局变量。该库还具有内部 static 数据,这些数据在 windows 之间共享。您只能使用以下策略之一获得多线程代码的可靠结果:
- 在一个线程内完成所有的window管理(包括输入)
- 使用互斥锁、信号量或任何 concurrency 技术似乎最好地管理单独的线程,这些线程 "own" 分开 windows。要在这里取得成功,一个线程必须拥有整个屏幕,从 curses 库 blocks 等待输入时开始,直到它更新屏幕并恢复等待输入。这比听起来更难。
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
子目录中):
- 同上显示
use_screen
。 - test_opaque 为
WINDOW
属性执行 "getters" - 下雨
use_window
- 蠕虫显示
use_window