2010-08-03 42 views
0

我正在使用ncurses在C中编写基于文本的客户端。程序的主循环直到检测到按键,然后处理它并继续等待另一按键。需要关于ncurses游标和线程的帮助

我有一个线程启动(在下面发布),阻塞(使用select)等待来自服务器的输入,当它接收到它时,将它添加到聊天日志缓冲区并将缓冲区打印到屏幕上。它完美的作品。

我知道ncurses不是线程安全的,但我对线程的理解是,只要我100%确定只有一个线程一次调用ncurses,它就能正常工作。

我的问题是与光标位置。

它是用move(height+1, curx); 行修改的,无论我传递给它什么值,ncurses似乎完全忽略了这个调用,并将我的光标置于不同的位置。我似乎无法影响它。

为了进一步解释问题,在我的主线程(按键循环)中,我使用了相同的互斥锁。当光标在这些代码段中更新时,它按计划运行。当它从下面的接收线程更新时,游标调用将被忽略。

任何想法?

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); 

    } 

+0

为什么在使用select时使用线程?不要过分复杂的事情! – mvds 2010-08-04 01:27:20

+0

你是对的还是错的。选择阻止UI在检查数据时工作的块。至少在我的测试中。 但是,我过了复杂的事情,最终解决了问题 – 2010-08-04 05:44:36

回答

0

可能为时已晚,对于这个问题的答案。

您没有指定要控制光标的窗口。我假设你想将光标放在chat_box或chat_window的(height + 1,curx)位置上。

可以在stdout窗口中使用移动功能控制光标,该窗口是原始终端,但不是在您创建的窗口(chat_box和chat_window)上。用于在用户创建的窗口中控制光标的功能是wmove。

int move(int y,int x);

int wmove(WINDOW * win,int y,int x);

希望这可以帮助其他人面临类似的问题。如果这不是正确的解决方案,请注意。