• Система автоматизации с открытым исходным кодом на базе esp8266/esp32 микроконтроллеров и приложения IoT Manager. Наша группа в Telegram

Нужна помощь МНОГОПОТОЧНОСТЬ

nikolz

Well-known member
Ну хорошо, тогда что Вы понимаете под потоком (thread) и задачей (task, process)?
Один процесс, приложение, задача как правило, имеет один или несколько потоков.
И это не зависит от количества ядер.
На одном вычислительном ядре Вы прекрасно можете смотреть художественный фильм со звуком. При этом на компьютере запускается одна задача - MediaPlayer, которая создает три потока - один поток читает данные из файла, другой получает сжатые (например, методом h.264) видеоданные, формирует последовательность кадров и выводит на экран. В то время как третий поток получает из этого же файла только аудиоданные, сжатые, например, методом MP3 дешифрует и выводит в динамики. Эти потоки выполняются параллельно с первым, нисколько не мешая ему. Дело в том, что расшифровка одного кадра занимает гораздо меньшее время, чем время показа этого кадра. Поэтому процессор может в оставшееся время декодировать звук. Оба потока большую часть времени находятся в ожидании: второй - обратного хода по кадрам монитора, а третий - завершения проигрывания звукового фрагмента аудиосистемой. Первый поток обеспечивает исходными данными два других. Потоки отличаются от процессов меньшей степенью изоляции друг от друга. При этом обмен данными происходит через общую память, в то время как процессы могут обмениваться данными только через глобальные объекты.
Голые вычисления встречаются достаточно редко (особенно в системах реального времени). В основном процессор находится в ожидании того или иного события, по которому выполняет те или иные действия. Именно благодаря этому Вы можете не только смотреть фильм со звуком, но и в то же время Ваш компьютер может выдавать что-то по локальной сети в интернет, проверять почту, загружать данные и многое другое без каких-либо "тормозов".
Хорошо и подробно вопросы потоков процессов и задач рассмотрены в книге Дж.Рихтера. Windoes для профессионалов: Создание эффективных Win32 приложений с учетом специфики 64-разрядной версии Windows.
---------------------
Так им определены процессы задания и потоки.
Я не буду пересказывать эту книгу, так как многое из нее использовал сам в своих разработках и считаю ее хорошим учебником.
---------------------------
 

Grem_line

New member
Хорошо и подробно вопросы потоков процессов и задач рассмотрены в книге Дж.Рихтера.
Вы утверждаете, что два потока не могут быть параллельно запущены на одном процессорном ядре.
Тогда что-же будет, если функцию createThread() - создание потока в Windows API - вызвать несколько раз подряд на одноядерном компе? ;)
 

nikolz

Well-known member
Вы утверждаете, что два потока не могут быть параллельно запущены на одном процессорном ядре.
Тогда что-же будет, если функцию createThread() - создание потока в Windows API - вызвать несколько раз подряд на одноядерном компе? ;)
Я уже объяснял. На одном процессоре два потока будут работать последовательно.
потому что просто нет железа чтобы работать параллельно.
У одного процессора один сумматор один умножитель и набор регистров один.
каждому потоку нужен процессор.
Поэтому на одном процессоре каждый из потоков будет работать по очереди.
 

Grem_line

New member
на одном процессоре каждый из потоков будет работать по очереди
В один момент времени будет работать только один поток, это так. Но при этом каждый поток не ждет завершения другого.
Вы же можете на компьютере одновременно слушать музыку, набирать текст в Word и отправлять в интернет здоровенный файл. При этом ни одно из этих действий не будет притормаживаться.
 

nikolz

Well-known member
В один момент времени будет работать только один поток, это так. Но при этом каждый поток не ждет завершения другого.
Вы же можете на компьютере одновременно слушать музыку, набирать текст в Word и отправлять в интернет здоровенный файл. При этом ни одно из этих действий не будет притормаживаться.
Вы путаете два момента.
Ожидание потоком своей очереди (В винде это 10 мс) и видимое торможение исполнения задачи для человека.
Что же касается слушания музыки, то в компе есть DMA - канал прямого доступа к памяти. Так вот музыка из памяти вне процессора идет на звуковую карту. Т е музыка играется вообще аппаратно.
Аналогично и отправки здоровенного файла в интернет это делаем DMA и контроллер Ethernet т е аппаратно.
Т е если у Вас один процессор то потоки будут получать возможность что-то делать последовательно при этом музыка и отправка файла выполняется аппаратно, если DMA нет, то услышите скрип тормозов.
 

=AK=

New member
На одном процессоре два потока будут работать последовательно.
На одном процессоре два потока будут работать поочередно. Ни один из потоков вообще говоря не должен дожидаться окончания работы другого потока. Они будут выполняться "по кусочкам", причем эти "кусочки" будут настолько мелким, что стороннему наблюдателю будет казаться, что оба потока выполняются одновременно .

Поэтому для одновременного вывода видео и музыки DMA не обязателен. Можно и программно выводить, без DMA, просто это менее эффективно. Но при достаточной производительности процессора вы не заметите никакой разницы. С DMA или без DMA, вам будет казаться что оба процесса выполняются параллельно и одновременно.
 
Последнее редактирование:

Grem_line

New member
если DMA нет, то услышите скрип тормозов
Не совсем так. Альтернативный вариант - использование механизма прерываний. Чтобы проиграть звуковой фрагмент достаточно разместить в памяти массив аудиоданных и дать звуковой подсистеме команду проиграть этот фрагмент. После этого можно переключиться на другую задачу.
То же самое с сетевой картой - принимаемые пакеты вызывают прерывания.
В ISR по прерываниям от различных источников взводятся семафоры, которые разблокируют задачи-обработчики. Так, контроллер SPI процессора A20 имеет внутренний FIFO на 64 байта. Его можно запрограммировать, чтобы он генерировал прерывание при заполнении FIFO на 2/3. По прерыванию можно читать столько байт, сколько фактически лежит в FIFO на момент чтения.
 

nikolz

Well-known member
Не совсем так. Альтернативный вариант - использование механизма прерываний. Чтобы проиграть звуковой фрагмент достаточно разместить в памяти массив аудиоданных и дать звуковой подсистеме команду проиграть этот фрагмент. После этого можно переключиться на другую задачу.
То же самое с сетевой картой - принимаемые пакеты вызывают прерывания.
В ISR по прерываниям от различных источников взводятся семафоры, которые разблокируют задачи-обработчики. Так, контроллер SPI процессора A20 имеет внутренний FIFO на 64 байта. Его можно запрограммировать, чтобы он генерировал прерывание при заполнении FIFO на 2/3. По прерыванию можно читать столько байт, сколько фактически лежит в FIFO на момент чтения.
Про прерывания я написал в самом начале.
Повторю.
Если один процессор то ос с потоками будет работать медленнее чем задача на основе колбеков и прерываний.
Собственно пошли по второму кругу.
 

Grem_line

New member
На одном процессоре два потока будут работать поочередно. Ни один из потоков вообще говоря не должен дожидаться окончания работы другого потока. Они будут выполняться "по кусочкам", причем эти "кусочки" будут настолько мелким, что стороннему наблюдателю будет казаться, что оба потока выполняются одновременно .
Да, это так работает в ОС типа Windows или Linux. Именно поэтому они и не являются системами жесткого реального времени. Каждый поток получает управление только в свой квант времени. Нет механизмов для пользователя активировать поток строго по событию. Внутренние системные драйверы работают иначе, но они складывают данные в очереди. Пользовательский поток получает информацию о наступлении события через функцию waitForSingleEvent(), которая работает через эти самые очереди.
Во встраиваемых системах реального времени принято использовать другие способы планирования многопоточности. Так основным является вытесняющее планирование, когда более высокоприоритетные потоки вытесняют менее приоритетные. При этом задание приоритетов ложится на разработчика целевого ПО. Так "кусочком" для потока в RTOS является декодирование одного кадра видео, одного фрагмента аудио, прием одного пакета по локальной сети. В таких системах чаще всего не решаются задачи вроде вычисления "сто пятого знака числа Пи" - это управляющие системы. Кстати, ESP - типичный представитель таких систем. Все действия происходят по событиям таким, как приход пакета по WiFi, срабатыванию таймера, нажатию кнопки и т.п. Обработка событий достаточно легкая и не должна занимать много времени. При необходимости обработка одного события может быть прервана обработкой другого, если приоритет обработчика выше.
 

nikolz

Well-known member
Да, это так работает в ОС типа Windows или Linux. Именно поэтому они и не являются системами жесткого реального времени. Каждый поток получает управление только в свой квант времени. Нет механизмов для пользователя активировать поток строго по событию. Внутренние системные драйверы работают иначе, но они складывают данные в очереди. Пользовательский поток получает информацию о наступлении события через функцию waitForSingleEvent(), которая работает через эти самые очереди.
Во встраиваемых системах реального времени принято использовать другие способы планирования многопоточности. Так основным является вытесняющее планирование, когда более высокоприоритетные потоки вытесняют менее приоритетные. При этом задание приоритетов ложится на разработчика целевого ПО. Так "кусочком" для потока в RTOS является декодирование одного кадра видео, одного фрагмента аудио, прием одного пакета по локальной сети. В таких системах чаще всего не решаются задачи вроде вычисления "сто пятого знака числа Пи" - это управляющие системы. Кстати, ESP - типичный представитель таких систем. Все действия происходят по событиям таким, как приход пакета по WiFi, срабатыванию таймера, нажатию кнопки и т.п. Обработка событий достаточно легкая и не должна занимать много времени. При необходимости обработка одного события может быть прервана обработкой другого, если приоритет обработчика выше.
Вы опять не правы. Вытеснение реализуется и в винде.
Все что Вы перечислили - это известные принципы построения многозадачных систем. Параллельностью здесь не катит. Лишь многоядерность создает возможность параллельности.
 

Grem_line

New member
Если один процессор то ос с потоками будет работать медленнее чем задача на основе колбеков и прерываний.
Почему Вы считаете, что обработчики прерываний и колбеков не создают отдельные потоки?
Это справедливо для ОС типа Виндовс и Линукс. Для любых ОСРВ потоки могут находиться в состоянии ожидания событий (в частности прерываний или колбеков) через семафоры.
 

Grem_line

New member
Все что Вы перечислили - это известные принципы построения многозадачных систем.
Так я Вам про известные принципы и толкую!:)
Параллельностью здесь не катит.
Дело только в терминологии. Я пользуюсь терминологией встраиваемых операционных систем реального времени.
Так, для примера, наш с Вами esp8266 принимает пакеты по WiFi в то время, как пользователь мигает светодиодом. И эти два дела он прекрасно делает параллельно на одном ядре.
Если Вам больше нравится - пускай псевдопараллельно.
 
Последнее редактирование:

=AK=

New member
Во встраиваемых системах реального времени принято использовать другие способы планирования многопоточности. Так основным является вытесняющее планирование, когда более высокоприоритетные потоки вытесняют менее приоритетные.
При "разбора азов" можно не углубляться в эти детали. Для начала надо достичь хотя бы базового понимания.
 

nikolz

Well-known member
Так я Вам про известные принципы и толкую!:)

Дело только в терминологии. Я пользуюсь терминологией встраиваемых операционных систем реального времени.
Нет не соглашусь. Если бы лишь в терминологии то я бы и не спорил.
Дело в скорости вычислений на одном ядре.
Часто в задачах таких как IOT нет надобности OCPB. А при одном процессоре и одной задаче концепция осрв лишь замедляет исполнение задачи и усложняет софт.
Но разработчики этого не понимают, так как для них потоки и задачи это одно и тоже и по умолчанию считают что если потоков много можно сделать то это все параллельно
А про то, что параллельно некому исполнять - ядро то одно просто не догадываются так как железо для них - черный ящик. (это концепция кроссплатформенности)
вот и городят IOT измерителя температуры на OCPB с многопоточностью на ESP.
 

Grem_line

New member
при одном процессоре и одной задаче концепция осрв лишь замедляет исполнение задачи и усложняет софт
:):):)
Вот простейшая задача: мигать тремя светодиодами каждым со своей некратной частотой.
На некоей ОСРВ такая задача выглядит примерно так:
Код:
static int Blink(int N, int M)
{
 for(;;)
 {
  toggle(N);
  taskDelay(M);
 }
}

int main()
{
taskSpawn("Blink1",Blink,1, 50); // Мигать 1 светодиодом с периодом 50 мс
taskSpawn("Blink2",Blink,2, 70); // Вторым с 70
taskSpawn("Blink3",Blink,3, 90); // Третьим с 90
return 0;
}
Где тут замедление и попробуйте проще без ОСРВ?
 

rst

Member
Пользовательский поток получает информацию о наступлении события через функцию waitForSingleEvent(), которая работает через эти самые очереди.
Какие такие очереди? Что за фантазии? Приведите ссылки/доказательства.
И EnterCriticalSection()/LeaveCriticalSection() - тоже через некие мифические "очереди"?
 

rst

Member
:):):)
Вот простейшая задача: мигать тремя светодиодами каждым со своей некратной частотой.
На некоей ОСРВ такая задача выглядит примерно так:
...
Где тут замедление и попробуйте проще без ОСРВ?
Без ОСРВ можно сделать ещё проще, использовав всего один таймер и переключая состояния лампочек в его ISR. И не потребуется 3 стека выделять...
 
Сверху Снизу