LINUX.ORG.RU

Потоки, время выполнения задачи


0

0

Проблема такая. Есть основная программа, там создаётся 5 потоков, которые работают параллельно, и практически, делают одно и тоже(отрисовывают свой кусочек графика). Проблема в том, что каждая задача должна работать ровно 1с. не больше и не меньше. Отрисовка занимает точно менее 1с, т.е. остаётся еще какое-то время. Вопрос, как сделать так, чтобы задача отдавал управление ровно через 1с? Если делать это сразу после завершения её операций, то, как я сказал, это будет менее 1с. Пока идея такая: получить системное время ДО, выполнить процедуру, получить ПОСЛЕ(в мс), и "доспать" (sleep) оставшееся время(1c - (t2 - t1)). Но.. тут происходят накладные расходы на вызов sleep() и получения сист. времени, которые тоже, вроде, должны быть как-то учтены. Может у кого будут другие идеи?

Одна задача не может выполняться на одном процессоре в течении 1с.
Максимальное время - MAX_TIMESLICE by default 800мс.
Если и увеличить это время, все равно не сможешь гарантировать, что задача будет выполняться 1сек, т.к. ядро Линукс - преемптивное, т.е в любой момент может найтись более важная задача, чем твоя, а твоя будет вытеснена.
Для передачи управления другому процессу смотри man sched_yield.

Или я не правильно понял, что тебе нужно?

dont
()

Я что-то не понял. Рисовать график разными потоками!?..

Если брать обычную персоналку, то все операции с графиками должны быть одно-поточными. Другое дело, что предварительные вычисления можно сделать в других потоках, но сама графика - в одном.

Или у тебя какой-то особенный случай? Совершенно не догоняю. Поясни, плз.

dave ★★★★★
()

Имхо, тут ошибка в дизайне. Вешать вопросы синхронизации в треды которые занимаются отрисовкой это неправильно. Сделай счётчик тредов, последний тред пусть какой-нить лок отпустит а тот код что ждёт завершения тредов сам пусть спит столько сколько нужно.

true_admin ★★★★★
()
Ответ на: комментарий от true_admin

Тут не то что ошибка, тут неверная постановка задачи. Так не делают.

Могу рассказать пример. После того как в очередной версии Java в модуле прорисовки через OpenGL убрали всю много-поточность рисования и сделали один поток, прорисовка стала быстрее.

Какой спрашивается смысл делать много потоков там, где будет до фига блокировок (внутри)? А рисование именно такая задача.

dave ★★★★★
()

Попытаться объяснить накой тебе этот бред: `отдавал управление ровно через 1с' и досыпать. Если тебе надо дождаться окончания всех тредов, делаешь pthread_join для всех тредов в цикле.

anonymous
()
Ответ на: комментарий от dave

> Какой спрашивается смысл делать много потоков там, где будет до фига блокировок (внутри)? А рисование именно такая задача.

Рисование как раз не такая задача. Потоки, рисующие картину по кускам вообще не пересекаются.

anonymous
()
Ответ на: комментарий от anonymous

>> Какой спрашивается смысл делать много потоков там, где будет до фига блокировок (внутри)? А рисование именно такая задача.

> Рисование как раз не такая задача. Потоки, рисующие картину по кускам вообще не пересекаются.

смотря что ты имеешь ввиду под рисованием. Если сам вручную меняешь побайтово-или-как-там буфер который потом преобразуешь в картинку, то да; если же рисуешь средствами системы графической - то контекст у тебя один, и без блокировок у тебя в лучшем случае нарисуется мусор или вылетит прога, в худшем - будет всё ок до поры до времени, на твоём компе, может быть.

anonymous
()
Ответ на: комментарий от anonymous

> если же рисуешь средствами системы графической > то контекст у тебя один, и без блокировок у тебя в лучшем случае нарисуется мусор или вылетит прога

Смотря как устроена система. В обычном случае обычно для потоков будет только буффер. Если рисуем одним цветом, все будет отлично. Если рисуем разными цветами перекрывающиеся примитивы, могут быть артефакты из-за неопределенного порядка рисования. Если рисуем с альфой (т.е. перед рисованием читам), будет некрасиво, да.

> в худшем - будет всё ок до поры до времени, на твоём компе, может быть.

Сказки.

anonymous
()
Ответ на: комментарий от anonymous

Да, саму задачу я не объяснил. Попытаюсь объяснить. В рамках КП по системам РВ пишется нечто, эмулирующее эту "систему реального времени". Согласно ТЗ есть следущее - 5 задач. Сама система работает как бы в двух режимах - однопроцессорном: в один и тот же момент времени может работать только одна задача. Но он пока не рассматривается. Рассматривается как раз "многопроцессорный" режим. (про формулировки меня не пинать, ибо не мои, не мной составлены, а взяты из ТЗ). В последнем режиме, каждая задача живет своей жизнью, ничем не прирывается и вызывается каждое dT супервизора(это "дельта t" и есть та 1с) Работа задачи состоит только в том, чтобы на графике отобразить своё состояние прямоугольником(пример где это все делается - на моём скрине). Так вот, каждая задача рисует саму себя. но, она должна отдать работу супервизору(иными словами вернуть свое состяние(отработала, активна, приостановлена и пр) ровно через 1с, но не ранее. т.е.всю 1 с она должна "работать"). Но отрисовка пикселя-двух займет гораздо менее 1 с, вот в чем и был вопрос.

мой скрин http://www.linux.org.ru/gallery/3346004.png

fukazzz
() автор топика
Ответ на: комментарий от fukazzz

Так это курсовой проект с заданным сверху ТЗ! Это несколько меняет дело. Хотя само ТЗ, конечно, странное.

dave ★★★★★
()
Ответ на: комментарий от fukazzz

Ф-ция sleep не гарантирует, что поток проспит в точности заданное время. Кажется, обычно предоставляется гарантия, что проспит не меньше. Поэтому предлагаю оставить ту же идею, но усыплять не на все оставшееся время, а периодически на меньшие промежутки, например,

пока (1c - (t2 - t1) > epsilon_t) {

если (1c - (t2 - t1) > max_t + min_t) уснуть на время max_t; иначе уснуть на время (1c - (t2 - t1));

обновить время t2; }

где min_t, max_t и epsilon_t - некоторые подобранные константы.

Получается, что мы последовательно подбираемся к 1 секунде. Что касается накладных расходов в виде вызова sleep и получения времени, то они неизбежны.

Вот, такая идея.

dave ★★★★★
()
Ответ на: комментарий от dave

Спасибо, такой подход мне кажется действительно более удачным. Если ничего более интересного не придумаю, то его и буду использовать.

fukazzz
() автор топика
Ответ на: комментарий от anonymous

святая простота

> Смотря как устроена система. В обычном случае обычно для потоков будет только буффер.

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

> Сказки.

в QT4 в треде енейблим виджеты. Формально вроде как не операция отрисовки - на MacOSX на тестовом прогоне всё ок, в Linux при определенном стечении обстоятельств на том же самом тесте прога тупо крошится (когда везет с порядком выполнения тредов). И вот случай когда всё работает OK - как раз и не везет, потому что потом на клиентской машине будет всё крошится, причем не у всех, и не всегда - и фиг ты нормально такое отловишь.

anonymous
()
Ответ на: комментарий от dave

1 секунду всё равно гарантировать невозможно, т.к. msleep(1) проспит не 1 мс, а некоторое кол-во миллисекунд, в зависимости от CONFIG_HZ. Если CONFIG_HZ = 250 Hz, то как минимум 4 мс., и т.д.

alex_custov ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.