2016-03-27 8 views
1

私がしなければならないラボのためにいくつかのスレッドを終了するのに問題があります。スレッドウィンドウをC言語で終了する

私は他のすべてのものが働いていると信じていますが、問題は最後にあります。基本的には、2つのスレッドを実行する必要があります。カウントアップするトップウィンドウと、カウントダウンするボトムウィンドウです。キーボードのクリックを入力すると、1つのウィンドウがカウントを停止します。 2回目のクリックを入力すると、もう1つのウィンドウもカウントを停止します。両方が停止すると、3秒の遅延があり、その後プログラムが終了します。

問題は、ボタンをクリックすると両方のウィンドウがカウントを停止し、プログラムを強制終了する必要があることです。誰も私が正しくやっていないことを見ることができますか?

/* 
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

無限ループを壊すと、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を返すこともできます。

+0

今もループしていません – Godfried23

+0

私はそれを使いました。そのif文の前にロックを解除する必要がありました。ありがとうございました! – Godfried23

+0

私の元の提案では、元の 'pthread_mutex_unlock'をそのまま残す必要がありました:) – dwks

関連する問題