The OpenNET Project / Index page

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




Версия для распечатки Пред. тема | След. тема
Новые ответы [ Отслеживать ]
Потоки, таймер и форма., !*! CynicRus, 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, но как-то это не принесло дивидендов. А потому и спрашиваю вашего совета.

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

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

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

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

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

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

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

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

        • Потоки, таймер и форма., !*! CynicRus, 22:54 , 15-Мрт-12 (4)
          >> 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;
          }

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

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


          • Потоки, таймер и форма., !*! gpl77, 13:15 , 16-Мрт-12 (6)
            > Код timer_get_message()

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




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

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