问题
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);
}
回答1:
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:
- 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 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.
Some of ncurses' test-programs illustrate the threading support (these are programs in the test
subdirectory of the sources):
- ditto shows
use_screen
. - test_opaque execises the "getters" for
WINDOW
properties - rain shows
use_window
- worm shows
use_window
回答2:
I am not sure what you want to do but this behaviour is quite normal. The thread that is active writes to the window and when the system makes a task switch the other thread writes to the window. Normal behaviour is to use only one thread that writes to the window. Other threads are supposed to do only some work. Anyway, if you are using more than one thread you have to synchronize them using events, mutexes, queues, semaphores or other methods.
来源:https://stackoverflow.com/questions/29545588/two-windows-one-modified-by-thread-random-output