在C中终止线程窗口

时间:2016-03-27 00:37:47

标签: c multithreading

我在为我必须做的实验室终止一些线程时遇到了一些麻烦。

我相信我已经完成了其他所有工作,但最终遇到了麻烦。所以基本上,我们需要运行两个线程,一个计数的顶部窗口和一个倒计时的底部窗口。我们应该发生的是当你进入键盘点击时,一个窗口将停止计数。当您输入第二次单击时,另一个窗口也将停止计数。一旦它们都停止,就会有三秒钟的延迟,之后程序将终止。

问题是,一旦我进入按钮点击,两个窗口都停止计数,然后我必须强制终止程序。谁能看到我做得不对劲?

/*
Godfried Weihs
Lab 5
CS3100
*/

#include <ncurses.h>
#include <unistd.h>
#include <stdlib.h>
#include <errno.h>
#include <pthread.h>

WINDOW *topwin, *botwin;

//mutex
pthread_mutex_t ncurses = PTHREAD_MUTEX_INITIALIZER;
pthread_t thread1, thread2;

void * countUp(void *ptr) {
int i = 0, key;

while (1) {
    //thread lock
    pthread_mutex_lock(&ncurses);
    wprintw(topwin, "Count up: %d\n", i++);
    wrefresh(topwin);
    key = getch();
    if (key != ERR) {
        break;
    }
    //thread unlock
    pthread_mutex_unlock(&ncurses);
}
return NULL;
}

void * countDown(void *ptr) {
int i = 0, key;

while (1) {
    //thread lock
    pthread_mutex_lock(&ncurses);
    wprintw(botwin, "Count down: %d\n", i--);
    wrefresh(botwin);
    key = getch();
    if (key != ERR) {
        break;
    }
    //thread unlock
    pthread_mutex_unlock(&ncurses);
}
return NULL;
}

int main(int argc, char **argv) {

int tlines, blines;

//thread lock
pthread_mutex_lock(&ncurses);
initscr();
cbreak();
keypad(stdscr, TRUE);
noecho();
nodelay(stdscr, TRUE);
tlines = LINES/2-1;
blines = LINES-tlines-1;
//thread unlock
pthread_mutex_unlock(&ncurses); 


//thread lock
pthread_mutex_lock(&ncurses);   
topwin = newwin(tlines, COLS, 0, 0);
//thread unlock
pthread_mutex_unlock(&ncurses);
scrollok(topwin, TRUE);

//thread lock
pthread_mutex_lock(&ncurses);
botwin = newwin(blines, COLS, tlines+1, 0);
//thread unlock
pthread_mutex_unlock(&ncurses);
scrollok(botwin, TRUE);

move(tlines, 0);
if (has_colors()) {
    //thread lock
    pthread_mutex_lock(&ncurses);
    start_color();
    init_pair(1, COLOR_GREEN, COLOR_BLACK);
    init_pair(2, COLOR_RED, COLOR_BLACK);
    init_pair(3, COLOR_BLUE, COLOR_BLACK);
    wattron(topwin, COLOR_PAIR(1));
    wattron(botwin, COLOR_PAIR(2));
    wattron(stdscr, COLOR_PAIR(3));
    //thread unlock
    pthread_mutex_unlock(&ncurses);
}
hline('_', 200);
refresh();

// Thread code goes HERE!
pthread_create(&thread1, (pthread_attr_t *) NULL,
            (void *) countUp, (void *) NULL);

pthread_create(&thread2, (pthread_attr_t *) NULL,
            (void *) countDown, (void *) NULL);     

//thread termination
pthread_join(thread1, (void *) NULL);
pthread_join(thread2, (void *) NULL);   

usleep(3000000);
endwin();   

return 0;
}

1 个答案:

答案 0 :(得分:1)

当你从无限循环中断开时,你忽略了解锁ncurses互斥锁,所以其他线程死锁。你应该使用例如。

if (key != ERR) {
    pthread_mutex_unlock(&ncurses);
    break;
}

最好是你可以放置你的锁和解锁,这样你永远不会陷入困境。例如,

bool running = true;
do {
    pthread_mutex_lock(&ncurses);
    running = do_stuff();
    pthread_mutex_unlock(&ncurses);
} while(running);

现在do_stuff()函数可以在任何时候返回false,而不用担心互斥量。