The OpenNET Project / Index page

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

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

"переключение задачи до завершения временного кванта"  +/
Сообщение от Нестор (ok) on 24-Фев-13, 22:54 
Задача: отслеживается событие и при его возникновении обрабатывается.
Решение:
while (1) {
    if ( <событие> ) {
        <обработка>
    }
}
Проблема: много холостых ходов цикла, загрузка процессора до 100%

В Windows решается просто:
while (1) {
    if ( <событие> ) {
        <обработка>
        continue;
    }
    else {
        Sleep (0);
    }
}
здесь функция Sleep(0) позволяет планировщику передать исполнение другому потоку до истечения кванта времени выделенного текущему потоку.

Вопрос: Как подобный механизм реализовать в UNIX ?

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

Оглавление

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


1. "переключение задачи до завершения временного кванта"  +/
Сообщение от elvenic email(??) on 25-Фев-13, 02:55 
> Решение:
> while (1) {
>  if ( <событие> ) {
>   <обработка>
>  }
> }
> Проблема: много холостых ходов цикла, загрузка процессора до 100%

Решение не совсем правильное. (Я, кстати, очень сильно удивлюсь если в Виндовсе при использовании Sleep() загрузка процессора будет не 100%).

Правильно - использовать select() (man 2 select) или poll() (man 2 poll), что-то типа

while (select(...)) {
  // event happened. Process it:
  ...
}

при этом внутри цикла нет ветки else со sleep() - select() сам ждет события, и поскольку он реализован через системный вызов, кернел знает что данный поток будет не активным пока не произойдет событие заданное параметрами select()'а, и может наиболее эффективно распорядится ресурсами системы - например, поток не будет активизирован просто чтобы убедится что событие еще не наступило и сказать sleep() в очередной раз.

select()/poll() работают ожидая события ввода/вывода на файловых дескрипторах (наличия данных для чтения, готовности к записи, возникновения ошибки), но это на самом деле не является существенным ограничением:

а) если событие которого вы ждете это событие ввода/вывода на файловом дескрипторе к которому вы имеете доступ, оно прямо транслируется в параметеры select()/poll();

б) если это какое-то иное событие, значит где-то в системе есть поток который висит на вызове функции, завершение которой и будет сигналом этого события (напр. ожидание завершения вызова функции интерфейса какой-то базы данных, или ожидание ответа от пользователя в потоке графического интерфейса, и т.д). В этом случае довольно легко организовать пару файловых дескрипторов (напр. функцией pipe() (man pipe)); поток который ожидает события в цикле while(select()) на самом деле ожидает наличия данных на выходном конце pipe'а, а поток который дождался завершения вызова функции, поставляет эти данные - пишет, например, всего 1 байт во входной конец pipe'а, после чего select() в другом потоке завершается и тело цикла while выполняется.

А кстати, man sched_yield чтобы почитать о функции которая отдает квант выделеный текущему потоку, хотя по-моему это не то что тут требуется.

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

3. "переключение задачи до завершения временного кванта"  +/
Сообщение от pavlinux (ok) on 25-Фев-13, 03:16 
> которая отдает квант выделенный текущему потоку

Ничё она не отдаёт, а говорит планировщику "елси нада, то могёшь меня переместить в конец очереди".
Более того, поведение родственных нитей зависит от типа приоритета: OTHER, BATCH, IDLE, FIFO, RR, DEADLINE;
C FIFOй мож ваще не переключится, а тормознёт, планировщик увидит, что у тя самый большой приоритет и вернёт
обратно на первое место к процессору.

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

2. "переключение задачи до завершения временного кванта"  +/
Сообщение от pavlinux (ok) on 25-Фев-13, 03:12 
> Вопрос: Как подобный механизм реализовать в UNIX ?

sched_yield()

---
И ваще, планировщики и проблемы разруливания процессов/нитей - это задачи
системного программирования, а не прикладного.

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

4. "переключение задачи до завершения временного кванта"  +/
Сообщение от Andrey Mitrofanov on 25-Фев-13, 09:27 
> И ваще, планировщики и проблемы разруливания процессов/нитей - это задачи
> системного программирования, а не прикладного.

Точно. Именно в этом уверены все :)прикладники.

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

5. "переключение задачи до завершения временного кванта"  +/
Сообщение от Нестор (ok) on 28-Фев-13, 09:14 
Спасибо за ответы. Я действительно немного промахнулся с темой, поищу в теме про потоки и нити.

К сожалению sched_yield() не помогает в данном случае, например:

   void main () {
      while (1) {
      }
   }

и

   void main () {
      while (1) {
         sched_yield ();
      }
   }

согласно top дают одинаковую загрузку CPU ~100%

Однако

   void main () {
      while (1) {
         usleep (1000);
      }
   }

резко уменьшает нагрузку до 0.3%

Наверное это и есть решение.

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

6. "переключение задачи до завершения временного кванта"  +/
Сообщение от Mr. Mistoffelees email on 28-Фев-13, 13:41 
Привет,

>  if ( <событие> ) {
>   <обработка>
>  }

Ответ зависит от того, в чем заключается обработка и точнее, насколько она должна быть в реальном времени. Лучший вариант, конечно, select() - есил есть возможность его использовать. usleep() позволит снизить нагрузку, а интервал зависит от того, как часто случается событие и насколько его обработка может подождать - напр., если "событие", это уборка за каким-то "мусором" (типа wait() после fork()), то и раз в секунду подойдет.

WWell,


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

7. "переключение задачи до завершения временного кванта"  +/
Сообщение от Нестор (ok) on 28-Фев-13, 14:26 
>[оверквотинг удален]
>>  if ( <событие> ) {
>>   <обработка>
>>  }
> Ответ зависит от того, в чем заключается обработка и точнее, насколько она
> должна быть в реальном времени. Лучший вариант, конечно, select() - есил
> есть возможность его использовать. usleep() позволит снизить нагрузку, а интервал зависит
> от того, как часто случается событие и насколько его обработка может
> подождать - напр., если "событие", это уборка за каким-то "мусором" (типа
> wait() после fork()), то и раз в секунду подойдет.
> WWell,

Доброго времени суток!

Реальная задача в получении пакетов на неблокированные сокеты:

   while (1) {
      . . .
      if ( !poll(. . .) ) {
         continue;
      }

      <обработка>

   }

select() не пробовал, но использование poll(), как в приведённом примере, оставляет загрузку CPU ~100%.

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

9. "переключение задачи до завершения временного кванта"  +/
Сообщение от Mr. Mistoffelees email on 13-Мрт-13, 14:36 
Привет,

> Реальная задача в получении пакетов на неблокированные сокеты:
> select() не пробовал, но использование poll(), как в приведённом примере, оставляет загрузку
> CPU ~100%.

Тогда попробуйте select(), он и есть ваше решение.

WWell,


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

13. "переключение задачи до завершения временного кванта"  +/
Сообщение от Аноним (??) on 01-Апр-13, 14:54 
> select() не пробовал, но использование poll(), как в приведённом примере, оставляет загрузку
> CPU ~100%.

Если загрузка 100%, то timeout=0. Ну уж тогда извините, что написали - то и получили.
select() не поможет, так как на уровне ядра всё равно реализован через poll().

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

8. "переключение задачи до завершения временного кванта"  +/
Сообщение от nanoo_linux on 12-Мрт-13, 20:05 
>[оверквотинг удален]
>   <обработка>
>   continue;
>  }
>  else {
>   Sleep (0);
>  }
> }
> здесь функция Sleep(0) позволяет планировщику передать исполнение другому потоку до истечения
> кванта времени выделенного текущему потоку.
> Вопрос: Как подобный механизм реализовать в UNIX ?

То что ты делаешь называется опрос. И это именно то, чего делать не стоит. Для этого алгоритма избежать 100% загрузки цпу невозможно. Вариант с usleep - костыль, который резко уменьшает время ответа системы.

Само получение ивента должно быть блокируемым. Самое простое решение - завести дескриптор при помощи man 2 pipe и с одной стороны - писать, а с другой - читать в блокирующем режиме ивенты.

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

10. "переключение задачи до завершения временного кванта"  +/
Сообщение от anonymous (??) on 15-Мрт-13, 21:07 
>[оверквотинг удален]
>> }
>> здесь функция Sleep(0) позволяет планировщику передать исполнение другому потоку до истечения
>> кванта времени выделенного текущему потоку.
>> Вопрос: Как подобный механизм реализовать в UNIX ?
> То что ты делаешь называется опрос. И это именно то, чего делать
> не стоит. Для этого алгоритма избежать 100% загрузки цпу невозможно. Вариант
> с usleep - костыль, который резко уменьшает время ответа системы.
> Само получение ивента должно быть блокируемым. Самое простое решение - завести дескриптор
> при помощи man 2 pipe и с одной стороны - писать,
> а с другой - читать в блокирующем режиме ивенты.

Зря, что ли, придумывали асинхронно-событийную парадигму?

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

11. "переключение задачи до завершения временного кванта"  +/
Сообщение от pavlinux (ok) on 16-Мрт-13, 22:17 
> Зря, что ли, придумывали асинхронно-событийную парадигму?

А не из теории что-нибудь?!


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

12. "переключение задачи до завершения временного кванта"  +/
Сообщение от anonymous (??) on 17-Мрт-13, 22:02 
>> Зря, что ли, придумывали асинхронно-событийную парадигму?
> А не из теории что-нибудь?!

http://libevent.org/ || http://software.schmorp.de/pkg/libev.html

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

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

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




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

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