【问题标题】:pthread and ncurses - why doesn't this lock work?pthread 和 ncurses - 为什么这个锁不起作用?
【发布时间】:2014-04-20 20:11:06
【问题描述】:

我正在学习 c 和 ncurses,并使用 halfdelay(1) 编写了一个简单的蛇游戏来半自动化它。当我添加线程时,它停止工作,因为我无法从键盘获得任何输入。

所以我写了一个简短的程序来尝试线程/ncurses 和互斥锁。该代码有 2 个线程,它们有自己的函数(fn 和 fn2)。当我在各自的函数调用中使用 wmove/wprint 运行它时,它可以工作(好吧,它打印到屏幕上!)我尝试实现互斥锁并将代码移动到另一个名为 print_to_screen() 的函数,但没有任何反应。

我添加了if(thread_id == pthread_self()) 在线程之间切换,但仍然没有任何反应。我添加了几行注释掉的行,显示 2 个线程到达 print_to_screen() 函数,但 if 循环中的代码根本没有运行。

请帮助我,我已经束手无策了 - 我什至尝试阅读 usr/inc.ncurses.h ,但人是没有帮助的!这是代码。如果您注释掉 2 个函数中的 wmove/wprint 位并取消注释 print_to_screen() 调用,您可以看到差异。 ncurses 设置来自 invisible-island 教程,如果有人知道他为什么将 (void) 放在他的 ncurses 调用前面,请告诉我。 TIA 为您提供任何帮助。

#include <stdlib.h>
#include <curses.h>
#include <signal.h>
#include <string.h> 
#include <time.h>
#include <pthread.h>
#include <sys/types.h>
#include <unistd.h>

void *myfunction(void *);
void *myfunction2(void *);

void print_to_screen(void);
static void finish(int);

pthread_t thread1, thread2;
pthread_mutex_t mx = PTHREAD_MUTEX_INITIALIZER;

int thread1_id, thread2_id, count, count2;
int done;   
int ch;

WINDOW *mywin;

int main(void){

    (void) signal(SIGINT, finish);      /* arrange interrupts to terminate */

    (void) initscr();      /* initialize the curses library */
    keypad(stdscr, TRUE);  /* enable keyboard mapping */
    (void) nonl();         /* tell curses not to do NL->CR/NL on output */
    (void) cbreak();       /* take input chars one at a time, no wait for \n */
    (void) echo();         /* echo input - in color */

      if (has_colors())
        {
        start_color();

        /*
         * Simple color assignment, often all we need.  Color pair 0 cannot
         * be redefined.  This example uses the same value for the color
         * pair as for the foreground color, though of course that is not
         * necessary:
         */
        init_pair(1, COLOR_RED,     COLOR_BLACK);
        init_pair(2, COLOR_GREEN,   COLOR_BLACK);
        init_pair(3, COLOR_YELLOW,  COLOR_BLACK);
        init_pair(4, COLOR_BLUE,    COLOR_BLACK);
        init_pair(5, COLOR_CYAN,    COLOR_BLACK);
        init_pair(6, COLOR_MAGENTA, COLOR_BLACK);
        init_pair(7, COLOR_WHITE,   COLOR_BLACK);
    }
    count = count2 = 0;
    done = 0;

    mywin = newwin(LINES, COLS, 0,0);
    keypad(mywin, TRUE);

    pthread_create( &thread1, NULL, myfunction, NULL);
    pthread_create( &thread2, NULL, myfunction2, NULL);

    pthread_join(thread1,  NULL);
    pthread_join(thread2,  NULL);

    finish(0);
    exit(0);
}

void *myfunction(void *ptr){

    thread1_id =  pthread_self();
    halfdelay(-1);

    while(1){
        ch = getch();
        if(ch == 'q') break;

        wmove(mywin, 5,2);
        wprintw(mywin, "Thread 1 at print");
        wmove(mywin, 10,count);
        waddch(mywin, ch);
        wrefresh(mywin);

        //print_to_screen();
        if(count++ >70) count = 0;
        nanosleep((struct timespec[]){{0, 250000000}}, NULL);
    }
    done = 1;
}

void *myfunction2(void *ptr){
    thread2_id =  pthread_self();

    while(1){
        if(done == 1) break;
        if(count++ >24) count = 0;
        wmove(mywin, 6,2);
        wprintw(mywin, "Thread 2 at print");
        wmove(mywin, count, 10);
        wprintw(mywin, "hello from thread 2");
        wrefresh(mywin); 

        //print_to_screen();
        nanosleep((struct timespec[]){{0, 250000000}}, NULL);
    }
}

void print_to_screen(){
    pthread_mutex_lock(&mx);

    //printw("PTHREAD ID = %d : ", pthread_self());
    //printw("thread1_id = %d : thread2_id = %d\n", thread1_id, thread2_id);

    if(pthread_self() == thread1_id){
        wmove(mywin, 5,2);
        wprintw(mywin, "Thread 1 at print");
        wmove(mywin, 10,count);
        waddch(mywin, ch);
        wrefresh(mywin);
    }


    if(pthread_self() == thread2_id){
        wmove(mywin, 6,2);
        wprintw(mywin, "Thread 2 at print");
        wmove(mywin, count, 10);
        wprintw(mywin, "hello from thread 2");
        wrefresh(mywin);
    }

    pthread_mutex_unlock(&mx);
}

static void finish(int sig)
{
    endwin();
    /* do your non-curses wrapup here */
}

【问题讨论】:

    标签: c locking pthreads mutex ncurses


    【解决方案1】:

    作为开始:

    int thread1_id, thread2_id, count, count2;
    

    应该是

    int count, count2;
    pthread_t thread1_id, thread2_id;
    

    另外,print_to_screen() 永远不会被调用。

    【讨论】:

    • 谢谢老兄,我以为 thread_self() 返回了 id,但我尝试像你说的那样更改它并且它有效。我知道 print_to_screen() 没有被调用,我将其注释掉以进行测试。取消注释并更改它并且它有效!
    • 我点击了绿色勾号,但没有足够的积分来投票,抱歉。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-10
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-04-06
    • 2013-03-10
    相关资源
    最近更新 更多