Курсор прыгает с библиотекой curses.h - PullRequest
1 голос
/ 06 декабря 2011

У меня есть проект с использованием проклятий и сокетов для создания говорящей программы. По сути, основной поток запускает два потока для управления двумя половинами экрана и другой поток для управления отправкой / получением по сети. Код кажется очень чистым, но по какой-то причине курсор время от времени скачет по экрану, казалось бы, случайно. Обычно около трех рядов в нем начинают прыгать повсюду. У меня нет функций mv ___ () из curses, поэтому я не понимаю, почему курсор на меня суетится.

Вот функция, вызываемая двумя потоками для управления двумя сторонами экрана. Любые идеи относительно того, что может вызвать это?

void *display(int sub)
{
    int bufSize = 10;
    char* buf = (char*)calloc(bufSize, sizeof(char));

    while(read(displayPipe[sub][0], buf, 1) > 0)
    {
        sem_wait(&displaySem);

        waddch(subWin[sub], buf[0]);
        wrefresh(subWin[sub]);

        sem_post(&displaySem);
    }

    free(buf);

    return NULL;

}

Вот функция, которая читает из сокета

void *netToPipe()
{       
    int bufSize = 10;
    char* buf = (char*)calloc(bufSize, sizeof(char));

    // read from talkfd
    while(read(talkfd, buf, 1) != EOF)
    {
        // print to the bottom of the screen
        if(write(displayPipe[1][1], buf, 1) < 0)
            (void)printf("Error writing to talkfd\n");
    }

    free(buf);

    return NULL;
}

А вот и конец main (), который читает с клавиатуры и пишет в нижнюю часть экрана (через канал) и в сокет.

while(1)
    {
        // get a key from the subwindow
        key = wgetch(subWin[0]);        

        // we are connected to a client
        if(talkfd > 0)  
        {
            // send across network
            write(talkfd, &key, 1);
            // copy to upper portion of the screen
            write(displayPipe[0][1], &key, 1);
        }
        // we are just talking to self
        else
        {
            // send to bottom of screen
            write(displayPipe[1][1], &key, 1);
            // send to top of screen
            write(displayPipe[0][1], &key, 1);  
        }
        refresh();

    } 

1 Ответ

1 голос
/ 06 декабря 2011

Учитывая огромную кучу ограничений, наложенных на вашу программу, я думаю, что абсолютное лучшее , которое вы можете сделать, это ограничить все curses функциями одним потоком -все входные данные, все выходные данные, все перерисовки и т. д. Сохраняйте потоки ввода-вывода выделенными для только сетевого ввода-вывода, а не для любых консольных операций ввода-вывода на основе curses.Поскольку стандартные проклятия на платформах, которые я хотел проверить, не поддерживают многопоточные операции, все еще нет никаких гарантий, что вы можете написать безошибочную программу таким образом, но это ваш лучший шанс.

Подобныйи гораздо более подход Unix-ish будет использовать несколько процессов вместо потоков.Таким образом, защищенная память не позволит различным процессам случайно перебирать глобальное или статическое хранилище curses, и у вас больше шансов на написание безошибочного программного обеспечения.

Конечно, большинство из них Подход Unix-ish будет использовать libevent или libev для мультиплексирования всего ввода-вывода в одном потоке и одном процессе.(Но это может также иметь проблемы при работе с curses. Это удивительное программное обеспечение, чьи корни были заложены три десятилетия назад ...)

...