The OpenNET Project / Index page

[ новости /+++ | форум | теги | ]

форумы  помощь  поиск  регистрация  майллист  вход/выход  слежка  RSS
"Потоки, таймер и форма."
Вариант для распечатки  
Пред. тема | След. тема 
Форум Программирование под UNIX (C/C++)
Изначальное сообщение [ Отслеживать ]

"Потоки, таймер и форма."  +/
Сообщение от CynicRus email on 15-Мрт-12, 11:16 
Доброго времени суток господа. Возникла проблема следующего рода. Есть подпрограмма таймер и подпрограмма создающая окно при помощи xlib, в котором отображается отсчет таймера. Когда обе подпрограмма выполняются в потоке main - все замечательно отрабатывает, но - мне необходимо раскидать их по разным потокам. Естественно использую pthread. Так вот - при попытке это сделать - ловлю необъяснимый Interrupted system call. Точнее - уже объяснимый. Вообщем - отделаю таймер от формы и выполняю в потоке - все замечательно, все работает. Запихиваю форму в отдельный  поток: Interrupted system call.
Таймер связан с формой следующим образом:
void timer_init()
{
    signal(SIGALRM, &timer_callback);
    struct timeval interval = { 1, 0 };
    struct timeval value = { 1, 0 };

    struct itimerval timerval;
    timerval.it_interval = interval;
    timerval.it_value = value;

    setitimer(ITIMER_REAL, &timerval, 0);
}

void timer_callback(int sign)
{
    if (timer_value > 0)
    {
        timer_value--;
    }

    window_repaint_send();
}

Обработка событий окна:
void window_loop()
{
    int ret;
    XEvent event;
    for (;;)
    {
        XNextEvent(display, &event);
        switch (event.type)
        {
        case Expose:
        {
            window_repaint();
            break;
        }
        case ResizeRequest:
        {
            XResizeRequestEvent *resize = (XResizeRequestEvent *) &event;

            window_width = resize->width;
            window_height = resize->height;

            break;
        }
        default:
        {
            break;
        }
        }
    }
}

void window_repaint_send()
{
    XExposeEvent expose = { Expose, 0, 1, display, window, 0, 0, window_width, window_height, 0 };
    XSendEvent(display, window, 0, ExposureMask, (XEvent *) &expose);
    XFlush(display);
}

void window_repaint()
{

    XClearArea(display, window, 0, 0, window_width, window_height, 0);


    XFontStruct *font = XLoadQueryFont(display, "10x20");
    if (!font)
    {
        exit(EXIT_FAILURE);
    }


    GC gc = XCreateGC(display, window, 0, NULL);

    XSetFont(display, gc, font->fid);

    char timer_message[100];

    timer_str(timer_message);

    int timer_message_pos_x = window_width / 2 - XTextWidth(font, timer_message, strlen(timer_message)) / 2;
    int timer_message_pos_y = window_height / 2 ;
    XDrawString(display, window, gc, timer_message_pos_x, timer_message_pos_y, timer_message, strlen(timer_message));

    char attention_message[100];
    if (timer_get_message(attention_message))
    {
        int attention_message_pos_x = window_width / 2 - XTextWidth(font, attention_message, strlen(attention_message)) / 2;
        int attention_message_pos_y = window_height / 2 + 30;

        XDrawString(display, window, gc, attention_message_pos_x, attention_message_pos_y, attention_message, strlen(attention_message));
    }

    XFreeGC(display, gc);
}

Подозреваю, что проблема в недрах window_loop, при обращении таймера к window_repaint_send и соответственным вызовом window_repaint. Пробовал через mutex заблокировать repaint, но как-то это не принесло дивидендов. А потому и спрашиваю вашего совета.

Ответить | Правка | Cообщить модератору

Оглавление

Сообщения по теме [Сортировка по времени | RSS]


1. "Потоки, таймер и форма."  +/
Сообщение от gpl77 (ok) on 15-Мрт-12, 12:30 
> и подпрограмма создающая окно при помощи xlib, в котором отображается отсчет
> таймера. Когда обе подпрограмма выполняются в потоке main - все замечательно
> отрабатывает, но - мне необходимо раскидать их по разным потокам. Естественно
> использую pthread.

Посмотрите в "Xlib − C Language X Interface"
"Using Xlib with Threads"

проверьте - собрана ли она у вас с поддержкой тредов.

Ответить | Правка | ^ к родителю #0 | Наверх | Cообщить модератору

2. "Потоки, таймер и форма."  +/
Сообщение от CynicRus email on 15-Мрт-12, 13:07 
>> и подпрограмма создающая окно при помощи xlib, в котором отображается отсчет
>> таймера. Когда обе подпрограмма выполняются в потоке main - все замечательно
>> отрабатывает, но - мне необходимо раскидать их по разным потокам. Естественно
>> использую pthread.
> Посмотрите в "Xlib − C Language X Interface"
> "Using Xlib with Threads"
> проверьте - собрана ли она у вас с поддержкой тредов.

XInitThreads() - отрабатывает корректно, собрана с поддержкой.

Ответить | Правка | ^ к родителю #1 | Наверх | Cообщить модератору

3. "Потоки, таймер и форма."  +/
Сообщение от gpl77 (ok) on 15-Мрт-12, 18:08 
> XInitThreads() - отрабатывает корректно, собрана с поддержкой.
> Пробовал через mutex заблокировать repaint, но как-то это не принесло дивидендов.

Должно приносить.
Попробуйте локировать в window_repaint_send
через XLockDisplay/UnLock

а что проиисходит в timer_get_message?
и зачем вы каждый раз создаете GC и выбираете фонты когда перерисовываете окно?
это, довольно, накладно.

Ответить | Правка | ^ к родителю #2 | Наверх | Cообщить модератору

4. "Потоки, таймер и форма."  +/
Сообщение от CynicRus email on 15-Мрт-12, 22:54 
>> XInitThreads() - отрабатывает корректно, собрана с поддержкой.
>> Пробовал через mutex заблокировать repaint, но как-то это не принесло дивидендов.
> Должно приносить.
> Попробуйте локировать в window_repaint_send
> через XLockDisplay/UnLock
> а что проиисходит в timer_get_message?
> и зачем вы каждый раз создаете GC и выбираете фонты когда перерисовываете
> окно?
> это, довольно, накладно.

Попробую, спасибо. Но завтра.
Код timer_get_message()

int timer_get_message(char *str)
{
    int min = 0;

    if (timer_value <= 60)
    {
        min = 1;
    }
    else if (timer_value <= 180)
    {
        min = 3;
    }
    else if (timer_value <= 300)
    {
        min = 5;
    }
    else
    {
        return 0;
    }

    sprintf(str, "Attention! Less than %i minutes!", min);

    return 1;
}

Ответить | Правка | ^ к родителю #3 | Наверх | Cообщить модератору

5. "Потоки, таймер и форма."  +/
Сообщение от CynicRus email on 16-Мрт-12, 10:33 
>[оверквотинг удален]
>     {
>         min = 5;
>     }
>     else
>     {
>         return 0;
>     }
>     sprintf(str, "Attention! Less than %i minutes!", min);
>     return 1;
> }

XLockDispay и XUnlockDisplay помогли. Спасибо огромное.


Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

6. "Потоки, таймер и форма."  +/
Сообщение от gpl77 (ok) on 16-Мрт-12, 13:15 
> Код timer_get_message()

я плохо знаю многопоточность, но, как я понимаю,
timer_get_message() и timer_callback у вас крутятся в разных тредах,
тогда работу с  timer_value надо, то же, локировать,
например, при инкрементировании

Ответить | Правка | ^ к родителю #4 | Наверх | Cообщить модератору

Архив | Удалить

Рекомендовать для помещения в FAQ | Индекс форумов | Темы | Пред. тема | След. тема




Партнёры:
PostgresPro
Inferno Solutions
Hosting by Hoster.ru
Хостинг:

Закладки на сайте
Проследить за страницей
Created 1996-2024 by Maxim Chirkov
Добавить, Поддержать, Вебмастеру