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();
Другие вопросы по тегам