需要有关 ncurses 游标和线程的帮助
我正在使用 ncurses 用 C 语言编写一个基于文本的客户端。程序的主循环只是阻塞,直到检测到按键,然后处理它并继续等待另一个按键。
我启动了一个线程(发布在下面),它阻止(使用 select)等待来自服务器的输入,当它接收到输入时,它会将其添加到聊天日志缓冲区并将缓冲区打印到屏幕上。它工作完美。
我知道 ncurses 不是线程安全的,但我对线程的理解是,只要我 100% 确定一次只有一个线程调用 ncurses,它就会正常工作。
我的问题是光标位置。
它通过行 move(height+1, curx); 进行修改。
无论我传递给它什么值,ncurses 似乎都会完全忽略该调用并将我的光标放在不同的位置。我似乎无法影响它。
为了进一步解释这个问题,在我的主线程(按键循环)中,我使用相同的互斥锁阻塞。当光标在这些代码部分中更新时,它会按计划工作。当从下面的接收线程更新它时,游标调用将被忽略。
有什么想法吗?
接收线程
char buf[512];
fd_set read_fds;
FD_ZERO(&read_fds);
int nbytes;
for (;;) {
read_fds = master;
select(sockfd+1, &read_fds, NULL, NULL, NULL);
pthread_mutex_lock(&mutexdisplay);
memset(&buf, 0, sizeof buf);
nbytes = recv(sockfd, buf, 512, 0);
buf[nbytes] = 0;
add_chatmsg(chatlog, &numchatlog, buf);
// erase window
werase(chat_window);
// redraw border
wborder(chat_window, '|', '|', '-', '-', '+', '+', '+', '+');
// scroll completely into the future
chatlogstart = numchatlog-1;
// print the chat log
print_chatlog(chatlog, &numchatlog, &chatlogstart, &height);
move(height+1, curx);
// refresh window
wrefresh(chat_box);
wrefresh(chat_window);
pthread_mutex_unlock(&mutexdisplay);
}
I am using ncurses to write a text-based client in C. The main loop of the program simply blocks until a keypress is detected and then handles it and continues to wait for another keypress.
I have a single thread I launch (posted below) that blocks (using select) waiting for input from the server and when it receives it adds it to the chat log buffer and prints the buffer to the screen. It works perfectly.
I know ncurses is not thread safe but my understanding of threads is that as long as I make 100% sure that only one thread is making calls to ncurses at a time, it will work fine.
My issue is with the cursor position.
It is modified with the line move(height+1, curx);
and no matter what values I pass to it, ncurses seems to ignore the call entirely and places my cursor at a different position. I cannot seem to influence it.
To further explain the problem, in my main thread (the keypress loop), I use the same mutex blocking. When the cursor is updated in those sections of code, it works as planned. When it is updated from the receive thread below, the cursor call is ignored.
Any ideas?
receive thread
char buf[512];
fd_set read_fds;
FD_ZERO(&read_fds);
int nbytes;
for (;;) {
read_fds = master;
select(sockfd+1, &read_fds, NULL, NULL, NULL);
pthread_mutex_lock(&mutexdisplay);
memset(&buf, 0, sizeof buf);
nbytes = recv(sockfd, buf, 512, 0);
buf[nbytes] = 0;
add_chatmsg(chatlog, &numchatlog, buf);
// erase window
werase(chat_window);
// redraw border
wborder(chat_window, '|', '|', '-', '-', '+', '+', '+', '+');
// scroll completely into the future
chatlogstart = numchatlog-1;
// print the chat log
print_chatlog(chatlog, &numchatlog, &chatlogstart, &height);
move(height+1, curx);
// refresh window
wrefresh(chat_box);
wrefresh(chat_window);
pthread_mutex_unlock(&mutexdisplay);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
回答这个问题可能为时已晚。
您没有指定要在哪个窗口上控制光标。我假设您希望光标位于 chat_box 或 chat_window 的 (height+1, curx) 位置。
人们可以在标准输出窗口中使用移动功能来控制光标,该窗口是原始终端,但不能在您创建的窗口(chat_box 和 chat_window)上控制。在用户创建的窗口中控制光标的函数是wmove。
int 移动(int y, int x);
int wmove(WINDOW *win, int y, int x);
希望这可以帮助其他面临类似问题的人。如果这不是正确的解决方案,请指出。
May be its too late for an answer to this question.
You didnt specify on which window you want to control the cursor. I am assuming that you wanted the cursor at the (height+1, curx) position of the chat_box or chat_window.
One can control the cursor with move funtion in the stdout widow which is the original terminal but not on the windows(chat_box and chat_window) you created. The function for for controlling the cursor in user created windows is wmove.
int move(int y, int x);
int wmove(WINDOW *win, int y, int x);
Hope this helps others facing similar problem. Please do point if this is not the correct solution.