多线程使用ncurses时,终端乱码
when use ncurses in multi-threaded , the terminal garbled
我用ncurses写的图书馆管理系统,多线程时终端乱码,我的layout有3个windows.
1.My 代号 ncurses.c
#include <stdio.h>
#include <ncurses.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
typedef struct _WIN_struct {
int startx, starty;
int height, width;
} WIN;
WIN winTitle; /* title win */
WIN winMenu; /* Main menu win */
WIN winNews; /* win news */
WINDOW *create_newwin(int height, int width, int starty, int startx) {
WINDOW *local_win;
local_win = newwin(height, width, starty, startx);
box(local_win, 0, 0);
wrefresh(local_win);
return local_win;
}
char *getTimeNow() {
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
return asctime(timeinfo);
}
void *threadfunc_title(void *p) {
WINDOW *windowTitle;
windowTitle = create_newwin(winTitle.height, winTitle.width, winTitle.starty, winTitle.startx);
/* show title and time */
for (;;) {
mvwprintw(windowTitle, winTitle.height/2, winTitle.width/2 - 10, "%s", "Library Management System");
mvwprintw(windowTitle, winTitle.height-2, winTitle.width-30, "%s", getTimeNow());
wrefresh(windowTitle);
sleep(1);
}
}
void *threadfunc_menu(void *p) {
WINDOW *windowMenu;
windowMenu = create_newwin(winMenu.height, winMenu.width, winMenu.starty, winMenu.startx);
for (;;) {
/* now do nothing */
sleep(1);
}
}
void *threadfunc_news(void *p) {
WINDOW *windowNews;
windowNews = create_newwin(winNews.height, winNews.width, winNews.starty, winNews.startx);
for (;;) {
wprintw(windowNews, "%d. %s,%s", getTimeNow(), 1, "a borrow a book from c");
wrefresh(windowNews);
wclear(windowNews);
sleep(5);
}
}
void initWin(WIN *p_win, int height, int width, int starty, int startx) {
p_win->height = height;
p_win->width = width;
p_win->starty = starty;
p_win->startx = startx;
}
int main(int argc, char *argv[])
{
pthread_t pidTitle;
pthread_t pidMenu;
pthread_t pidNews;
initscr();
start_color();
cbreak();
keypad(stdscr, TRUE);
noecho();
/* init location */
initWin(&winTitle, LINES*0.2, COLS, 0 , 0);
initWin(&winMenu, LINES*0.7, COLS*0.7, LINES*0.25, 0);
initWin(&winNews, LINES*0.7, COLS*0.2, LINES*0.25, COLS*0.7);
pthread_create(&pidTitle, NULL, threadfunc_title, NULL);
pthread_create(&pidMenu, NULL, threadfunc_menu, NULL);
pthread_create(&pidNews, NULL, threadfunc_news, NULL);
pthread_join(pidTitle, NULL);
pthread_join(pidMenu, NULL);
pthread_join(pidNews, NULL);
endwin();
return 0;
}
2.Three三个线程windows,thread_func_xxx()是pthread_create()的第三个参数。
3.Compile 和 运行
$ gcc ncurses.c -lncurses -lpthread -o ncurses
$ ./ncurses
然后,我终端乱码
ps:
1.I 已将 -lncurses
更改为 -lncursesw
,但没有效果。
2.if你没有安装ncurses,可以关注this.
简短:该示例将无法运行,因为用于更新屏幕的低级函数共享 非互斥的数据。如果你编译 ncurses 时使用 pthread option, that improves the re-entrancy 的高级函数并添加 一些 互斥体,就可以使用多线程。
我用ncurses写的图书馆管理系统,多线程时终端乱码,我的layout有3个windows.
1.My 代号 ncurses.c
#include <stdio.h>
#include <ncurses.h>
#include <pthread.h>
#include <time.h>
#include <unistd.h>
typedef struct _WIN_struct {
int startx, starty;
int height, width;
} WIN;
WIN winTitle; /* title win */
WIN winMenu; /* Main menu win */
WIN winNews; /* win news */
WINDOW *create_newwin(int height, int width, int starty, int startx) {
WINDOW *local_win;
local_win = newwin(height, width, starty, startx);
box(local_win, 0, 0);
wrefresh(local_win);
return local_win;
}
char *getTimeNow() {
time_t rawtime;
struct tm *timeinfo;
time(&rawtime);
timeinfo = localtime(&rawtime);
return asctime(timeinfo);
}
void *threadfunc_title(void *p) {
WINDOW *windowTitle;
windowTitle = create_newwin(winTitle.height, winTitle.width, winTitle.starty, winTitle.startx);
/* show title and time */
for (;;) {
mvwprintw(windowTitle, winTitle.height/2, winTitle.width/2 - 10, "%s", "Library Management System");
mvwprintw(windowTitle, winTitle.height-2, winTitle.width-30, "%s", getTimeNow());
wrefresh(windowTitle);
sleep(1);
}
}
void *threadfunc_menu(void *p) {
WINDOW *windowMenu;
windowMenu = create_newwin(winMenu.height, winMenu.width, winMenu.starty, winMenu.startx);
for (;;) {
/* now do nothing */
sleep(1);
}
}
void *threadfunc_news(void *p) {
WINDOW *windowNews;
windowNews = create_newwin(winNews.height, winNews.width, winNews.starty, winNews.startx);
for (;;) {
wprintw(windowNews, "%d. %s,%s", getTimeNow(), 1, "a borrow a book from c");
wrefresh(windowNews);
wclear(windowNews);
sleep(5);
}
}
void initWin(WIN *p_win, int height, int width, int starty, int startx) {
p_win->height = height;
p_win->width = width;
p_win->starty = starty;
p_win->startx = startx;
}
int main(int argc, char *argv[])
{
pthread_t pidTitle;
pthread_t pidMenu;
pthread_t pidNews;
initscr();
start_color();
cbreak();
keypad(stdscr, TRUE);
noecho();
/* init location */
initWin(&winTitle, LINES*0.2, COLS, 0 , 0);
initWin(&winMenu, LINES*0.7, COLS*0.7, LINES*0.25, 0);
initWin(&winNews, LINES*0.7, COLS*0.2, LINES*0.25, COLS*0.7);
pthread_create(&pidTitle, NULL, threadfunc_title, NULL);
pthread_create(&pidMenu, NULL, threadfunc_menu, NULL);
pthread_create(&pidNews, NULL, threadfunc_news, NULL);
pthread_join(pidTitle, NULL);
pthread_join(pidMenu, NULL);
pthread_join(pidNews, NULL);
endwin();
return 0;
}
2.Three三个线程windows,thread_func_xxx()是pthread_create()的第三个参数。
3.Compile 和 运行
$ gcc ncurses.c -lncurses -lpthread -o ncurses
$ ./ncurses
然后,我终端乱码
ps:
1.I 已将 -lncurses
更改为 -lncursesw
,但没有效果。
2.if你没有安装ncurses,可以关注this.
简短:该示例将无法运行,因为用于更新屏幕的低级函数共享 非互斥的数据。如果你编译 ncurses 时使用 pthread option, that improves the re-entrancy 的高级函数并添加 一些 互斥体,就可以使用多线程。