C - ncurses и два параллельных потока
Эта программа должна быть тривиальной попыткой запустить два параллельных потока, которые нужно записать на одном экране.
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <pthread.h>
#include <ncurses.h>
void *function1(void *arg1);
void *function2(void *arg2);
int main(int argc, char *argv[])
{
printf("hello");
initscr();
printw("screen on\n");
pthread_t function1t;
pthread_t function2t;
if( pthread_create( &function1t, NULL, function1, NULL) < 0)
{
printw("could not create thread 1");
return 1;
}
if( pthread_create( &function2t, NULL, function2, NULL) < 0)
{
printw("could not create thread 2");
return 1;
}
endwin();
return 0;
}
void *function1(void *arg1)
{
printw("Thread 1\n");
while(1);
}
void *function2(void *arg2)
{
printw("Thread 2\n");
while(1);
}
Но это даже не печатать hello
в начале. В чем дело? Как обрабатывать уникальный экран в такой программе с помощью двух потоков?
Обновление: положить refresh();
после каждого printw
производит следующий вывод
screen on
Thread 1
Thread 2
$
Где $ это подсказка. Таким образом, программа печатает строку, но она помещает (очевидно) случайным образом некоторые неожиданные символы новой строки, и это заканчивается. Это не должно из-за while(1)
инструкции в обеих темах!
2 ответа
curses/ncurses в обычной конфигурации не поддерживает потоки, и для этого всегда рекомендуется запускать curses в одном потоке. Начиная с ncurses 5.7, для многопоточных приложений была обеспечена элементарная поддержка, если библиотека настроена (время компиляции) для использования мьютексов и дополнительных точек входа.
Что касается мьютексов, то практически все учебники по потокам POSIX охватывают это. Вот пример: программирование потоков POSIX
Это не печать hello
строка, но она быстро очищается с помощью инструкции initscr()
:
Код initscr определяет тип терминала и инициализирует все структуры данных curses. initscr также вызывает обновление первого вызова, чтобы очистить экран. Если возникают ошибки, initscr записывает соответствующее сообщение об ошибке в стандартную ошибку и завершает работу; в противном случае указатель возвращается в stdscr.
printw
печатает как положено, потому что вы не обновляете. Вы должны использовать refresh()
после каждого printw
:
printw("screen on\n");
refresh();