ncurses & pthread
От: Diversant  
Дата: 03.07.09 06:14
Оценка:
Здравствуйте!
Пишу программу с использованием ncurses и pthread.
Нужно выводить в двух разных окошках работу потоков.
Проблема в том, что программа работает нормально только тогда, когда в окно выводит только один поток. Если раскомментировать строки запуска второго потока, программа выводит на терминал "мусор" и вылетает с "Segmentation fault".

Копмиляция:
gcc prog1.c -D_REENTERANT -I/usr/include/nptl -L/usr/lib/nptl -lncurses -lpthread -o prog1




//************ prog1.c *************
 
#include <ncurses.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
 
WINDOW *win1, *win2, *subwin1, *subwin2, *subwinstd;
pthread_t tid1, tid2;
int rez;
 
void endncurses();
void *funct1();
void *funct2();
 
main(int argc, int *argv[])
{
initscr();
cbreak();
noecho();
curs_set(0);
 
start_color();
init_pair(1, COLOR_GREEN, COLOR_BLACK);
bkgd(COLOR_PAIR(1));
box(stdscr, ACS_VLINE, ACS_HLINE);
refresh();
 
win1 = newwin(12, 25, 2, 2);
wbkgd(win1, COLOR_PAIR(1));
box(win1, ACS_VLINE, ACS_HLINE);
subwin1 = subwin(win1, 10, 23, 3, 3);
scrollok(subwin1, TRUE);
wrefresh(win1);
 
win2 = newwin(12, 25, 2, 32);
wbkgd(win2, COLOR_PAIR(1));
box(win2, ACS_VLINE, ACS_HLINE);
subwin2 = subwin(win2, 10, 23, 3, 33);
scrollok(subwin2, TRUE);
wrefresh(win2);
 
// thread #1
if ((rez = pthread_create(&tid1, NULL, funct1, NULL)) != 0)
        {
        endncurses();
        printf("Error create thread #1\n");
        exit(0);
        }
 
// thread #2
//if ((rez = pthread_create(&tid2, NULL, funct2, NULL)) != 0)
//      {
//      endncurses();
//      printf("Error create thread #2\n");
//      exit(0);
//      }
 
 
getch();
endncurses();
return 0;
}
 
void endncurses()
{
delwin(subwin2);
delwin(subwin1);
delwin(win2);
delwin(win1);
erase();
refresh();
endwin();
}
 
void *funct1()
{
int j;
j = 0;
while (1)
        {
        wprintw(subwin1, "Thread #1 --- %d\n", j);
        wrefresh(subwin1);
        j++;
        }
}
 
void *funct2()
{
int k;
k = 0;
while (1)
        {
        wprintw(subwin2, "Thread #2 --- %d\n", k);
        wrefresh(subwin2);
        k++;
        }
}


Как решить?..
Re: ncurses & pthread
От: MaxGl Украина  
Дата: 03.07.09 07:07
Оценка:
Здравствуйте, Diversant, Вы писали:
//************ prog1.c *************
 
#include <ncurses.h>
#include <stdlib.h>
#include <pthread.h>
#include <errno.h>
 
WINDOW *win1, *win2, *subwin1, *subwin2, *subwinstd;
pthread_t tid1, tid2;
int rez;
static pthread_mutex_t curses_mutex;

void endncurses();
void *funct1();
void *funct2();
 
int main(int argc, int *argv[])
{
initscr();
cbreak();
noecho();
curs_set(0);
 
start_color();
init_pair(1, COLOR_GREEN, COLOR_BLACK);
bkgd(COLOR_PAIR(1));
box(stdscr, ACS_VLINE, ACS_HLINE);
refresh();
 
win1 = newwin(12, 25, 2, 2);
wbkgd(win1, COLOR_PAIR(1));
box(win1, ACS_VLINE, ACS_HLINE);
subwin1 = subwin(win1, 10, 23, 3, 3);
scrollok(subwin1, TRUE);
wrefresh(win1);
 
win2 = newwin(12, 25, 2, 32);
wbkgd(win2, COLOR_PAIR(1));
box(win2, ACS_VLINE, ACS_HLINE);
subwin2 = subwin(win2, 10, 23, 3, 33);
scrollok(subwin2, TRUE);
wrefresh(win2);
/* Нам нужен мьютекс ... */
pthread_mutex_init(&foo_mutex, NULL);
// thread #1
if ((rez = pthread_create(&tid1, NULL, funct1, NULL)) != 0)
        {
        endncurses();
        printf("Error create thread #1\n");
        exit(0);
        }
 
// thread #2
if ((rez = pthread_create(&tid2, NULL, funct2, NULL)) != 0)
      {
      endncurses();
      printf("Error create thread #2\n");
      exit(0);
      }
 
 
getch();
endncurses();
return 0;
}
 
void endncurses()
{
delwin(subwin2);
delwin(subwin1);
delwin(win2);
delwin(win1);
erase();
refresh();
endwin();
}
 
void *funct1()
{
int j;
j = 0;
while (1)
        {
        /*... который спасет нас от одновременного изменения 
          внутренностей subwin1 тут...
         */
        pthread_mutex_lock(&curses_mutex);
        wprintw(subwin1, "Thread #1 --- %d\n", j);
        wrefresh(subwin1);
        pthread_mutex_unlock(&curses_mutex);
        j++;
        }
}
 
void *funct2()
{
int k;
k = 0;
while (1)
        {
        /*... и тут */
        pthread_mutex_lock(&curses_mutex);
        wprintw(subwin2, "Thread #2 --- %d\n", k);
        wrefresh(subwin2);
        pthread_mutex_unlock(&curses_mutex);
        k++;
        }
}
Re[2]: ncurses & pthread
От: MaxGl Украина  
Дата: 03.07.09 07:09
Оценка:
Здравствуйте, MaxGl, Вы писали:
Копипастил и набажил
Было:
pthread_mutex_init(&foo_mutex, NULL);

Должно быть:
pthread_mutex_init(&curses_mutex, NULL);
Re: ncurses & pthread
От: ДимДимыч Украина http://klug.org.ua
Дата: 03.07.09 07:12
Оценка:
Здравствуйте, Diversant, Вы писали:

D>Как решить?..


Насколько мне известно, ncurses не является thread-safe библиотекой. В голове крутится что-то про curs_threads: use_screen() и use_window() в частности.
Обязательно бахнем! И не раз. Весь мир в труху! Но потом. (ДМБ)
Re[2]: ncurses & pthread
От: Diversant  
Дата: 03.07.09 09:10
Оценка:
Здравствуйте, MaxGl

Спасибо за подсказку! Работает!
Re[2]: ncurses & pthread
От: Diversant  
Дата: 03.07.09 09:12
Оценка:
Здравствуйте, ДимДимыч, Вы писали:

ДД>Здравствуйте, Diversant, Вы писали:


D>>Как решить?..


ДД>Насколько мне известно, ncurses не является thread-safe библиотекой. В голове крутится что-то про curs_threads: use_screen() и use_window() в частности.


Спасибо! Буду курить маны по curs_threads...
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.