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

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

Grem_line

New member
Чтобы исключить простаивание процессора используется механизм прерываний и колбеков.
При этом достигается большее быстродействие так как не тратится время для бессмысленного переключения процессора между потоками.
Как раз прерывания и вызывают переключение между потоками. В операционных системах реального времени нет "бессмысленного" переключения между потоками. Переключение происходит только в случае, если более приоритетный процесс требует немедленного исполнения. Это переключение инициируется в любом случае прерыванием. Еще переключение может происходить по запросу активной задачи (потока):
Когда поток ожидает завершения какой-либо аппаратной операции, производится переключение на самый приоритетный из ожидающих потоков, а текущий задерживается до наступления прерывания по завершению. Также в системах реального времени процедура delay() не выполняет пустые циклы, а задерживает выполнение потока на заданное время. В это время выполняются другие потоки в соответствии с приоритетами.
На одном процессоре многопоточность лишь тормозит вычисления.
Типичный пример - выдача данных в COM-порт. Можно выдавать байты, ожидая готовности передатчика, но тогда до тех пор, пока не выдастся последний байт, процессор не сможет ничем больше заниматься.
А можно подсунуть контроллеру СОМ первый байт и заниматься другими делами, по прерыванию по готовности передатчика обработчик прерывания должен просто подсунуть следующий байт.
Таким образом, драйвер СОМ-порта организует новый поток, занимающийся выдачей массива данных.
Можно таким образом одновременно выдавать разные данные по десятку различных СОМ-портов на фоне каких-либо математических вычислений.
Конечно, вычисления будут выполняться несколько медленнее из-за прерываний, но общее повышение быстродействия налицо!
 

nikolz

Well-known member
Как раз прерывания и вызывают переключение между потоками. В операционных системах реального времени нет "бессмысленного" переключения между потоками. Переключение происходит только в случае, если более приоритетный процесс требует немедленного исполнения. Это переключение инициируется в любом случае прерыванием. Еще переключение может происходить по запросу активной задачи (потока):
Когда поток ожидает завершения какой-либо аппаратной операции, производится переключение на самый приоритетный из ожидающих потоков, а текущий задерживается до наступления прерывания по завершению. Также в системах реального времени процедура delay() не выполняет пустые циклы, а задерживает выполнение потока на заданное время. В это время выполняются другие потоки в соответствии с приоритетами.

Типичный пример - выдача данных в COM-порт. Можно выдавать байты, ожидая готовности передатчика, но тогда до тех пор, пока не выдастся последний байт, процессор не сможет ничем больше заниматься.
А можно подсунуть контроллеру СОМ первый байт и заниматься другими делами, по прерыванию по готовности передатчика обработчик прерывания должен просто подсунуть следующий байт.
Таким образом, драйвер СОМ-порта организует новый поток, занимающийся выдачей массива данных.
Можно таким образом одновременно выдавать разные данные по десятку различных СОМ-портов на фоне каких-либо математических вычислений.
Конечно, вычисления будут выполняться несколько медленнее из-за прерываний, но общее повышение быстродействия налицо!
Чтобы понять, чем отличается многопоточность от механизма прерываний и почему просто прерывания будут быстрее
см. книгу Рихтер Дж. Windows. Создание эффективных Win32-приложений с учётом специфики 64-разрядной версии Windows
 

Алексей.

Active member
Конечно, вычисления будут выполняться несколько медленнее из-за прерываний, но общее повышение быстродействия налицо!
Вы сами то пробовали использовать то о чем пишите на одном ядре?
На esp32 с использованием freertos строю два таска,
один таск работает с spi в режиме slave, получает данные и сохраняет их в очередь,
другой таск берет данные из очереди и отправляет в ip,
wifi на модуле настроен в режиме AP.
Мастером работает другой mcu, каждые 2,5 миллисекунды выполняет транзакцию, отправляет 1,5К байт данных.
Сначала я не предавал значения, на каком ядре поднимать таск для работы с spi, поднимал таск без указания ядра,
если таск запускался на нулевом ядре, получал потери пакетов на spi пачками, когда какому либо wifi клиенту вдруг захотелось соединиться точкой доступа на esp32, вычисления выполняемые при аутентификации занимали очень много времени, про spi работающем на нулевом ядре можно было забыть, точные замеры лагов я не делал, субъективно более 20-ти миллисекунд.
После того как запустил таск работающий слейвом с spi на первом ядре, никаких потерь на spi больше не было.
Как решить эту задачу на esp8266 с одним ядром даже не представляю.
А вы говорите вычисления медленнее выполняться будут...
Вычисления выполняемые при аутентификации, на которые вы повлиять не можете, мешают работе тасков, работающих на этом же ядре.
 

Grem_line

New member
см. книгу Рихтер Дж. Windows.
Никогда ни Windows, ни Linux не были операционными системами реального времени!
Вы сами то пробовали использовать то о чем пишите на одном ядре?
Не просто пробовал - делаю это постоянно! Я являюсь разработчиком встраиваемой операционной системы реального времени Multex. Разработка была начата еще в 1998 году. В настоящее время тысячи устройств работают под управлением этой ОС. Это устройства технического зрения, робототехники, системы кодирования/декодирования видеопотоков в реальном времени.
 
  • Like
Реакции: =AK=

Алексей.

Active member
Не просто пробовал - делаю это постоянно!
Поделитесь опытом, как на одном ядре esp8266, обеспечить многопоточность таким образом, чтоб пропреоритарные драйвера wifi на мешали работать таскам, критичным ко времени выполнения, фактически обрабатывающие прерывания.
 

nikolz

Well-known member
Никогда ни Windows, ни Linux не были операционными системами реального времени!

Не просто пробовал - делаю это постоянно! Я являюсь разработчиком встраиваемой операционной системы реального времени Multex. Разработка была начата еще в 1998 году. В настоящее время тысячи устройств работают под управлением этой ОС. Это устройства технического зрения, робототехники, системы кодирования/декодирования видеопотоков в реальном времени.
Строить можете что угодно. Но на одном процессоре нельзя параллельно выполнять задачи. Это как бежать по двум дорогам одновременно одному бегуну.
Вы очевидно путаете многозадачность и многопоточность.
Реальное время и многопоточность это две большие разницы.
Относительно ОСРВ это лишь терминология.
Так как время реакции на событие - вещь относительная. при определенных условиях и Windows, и Linux вполне будут работать ка системы реального времени .
 

Grem_line

New member
Поделитесь опытом, как на одном ядре esp8266, обеспечить многопоточность таким образом, чтоб пропреоритарные драйвера wifi на мешали работать таскам
Я не имею опыта работы с esp - только сейчас начал с ней возиться. Но поскольку есть версии ПО на базе FreeRTOS, то смею предположить, что это вполне возможно. Драйвера WiFi тоже работают по прерываниям, поэтому главное, чтобы обработчики прерываний занимали достаточно короткое время, чтобы не терялись другие прерывания. В "нормальных" RTOS для этого обычно используются семафоры. В обработчиках ISR выполняется только самое необходимое для отбоя прерывания и поднимается семафор. Все остальное выполняют задачи, ожидающие у этого семафора.
 

Grem_line

New member
Но на одном процессоре нельзя параллельно выполнять задачи. Это как бежать по двум дорогам одновременно одному бегуну.
Извините, но Вы говорите полную ерунду! Многоядерные процессоры появились сравнительно недавно, а вот многозадачные операционные системы - еще в середине прошлого века!
Вы что-нибудь слышали о переключении контекста процессора? Еще Intel 386 уже имел аппаратную поддержку этого. Не так давно выпускались планшеты под Android на Allwinner A13 - это одноядерный Cortex A8. Вы будете утверждать, что на них нельзя параллельно выполнять задачи? Или нельзя параллельно запустить два и больше приложений на WinXP на одноядерном Intel?
Вы очевидно путаете многозадачность и многопоточность.
Вовсе нет! Многопоточность отличается от многозадачности лишь тем, что потоки одной задачи выполняются в едином адресном пространстве. И то не всегда - в WxWorks, задачами называются по сути потоки.
при определенных условиях и Windows, и Linux вполне будут работать ка системы реального времени
Никогда на фирменных ядрах. Это связано с тем, что для обработки событий в них используются очереди. Время реакции не гарантировано!
 

nikolz

Well-known member
Извините, но Вы говорите полную ерунду! Многоядерные процессоры появились сравнительно недавно, а вот многозадачные операционные системы - еще в середине прошлого века!
Вы что-нибудь слышали о переключении контекста процессора? Еще Intel 386 уже имел аппаратную поддержку этого. Не так давно выпускались планшеты под Android на Allwinner A13 - это одноядерный Cortex A8. Вы будете утверждать, что на них нельзя параллельно выполнять задачи? Или нельзя параллельно запустить два и больше приложений на WinXP на одноядерном Intel?

Вовсе нет! Многопоточность отличается от многозадачности лишь тем, что потоки одной задачи выполняются в едином адресном пространстве. И то не всегда - в WxWorks, задачами называются по сути потоки.

Никогда на фирменных ядрах. Это связано с тем, что для обработки событий в них используются очереди. Время реакции не гарантировано!
Ну ерунду пока говорите Вы.
еще раз обращаю внимание на Ваш вопрос - МНОГОПОТОЧНОСТЬ это не МНОГОЗАДАЧНОСТЬ
теперь немного о ликвидации вашей безграмотности.
Для реализации многозадачности не имеет значение число ядер.
Для многозадачности нужен лишь таймер
и для защиты задач друг от друга аппаратный механизм переключения памяти или как его называли ранее - режим супервизора.
---------------------------------
Вот в 386 и был для этой цели введен разряд управления памятью.
-------------------------------
Далее читайте в инете.
И не путайте многопотоковость с многозадачностью.
 

Grem_line

New member
Вот в 386 и был для этой цели введен разряд управления памятью.
Разряд? ;) А про таблицы дескрипторов задач слышали? Про таблицы виртуальных адресов?Про блоки управления задачами? Это огромная подсистема, а не "разряд управления памятью".
Чем-же по-вашему отличается многозадачность от многопоточности?
Что делает по-вашему функция createThread() в WinAPI?
Thread, поток (нить) по аглицки - это отдельный вычислительный процесс, организованный в рамках одной задачи, в ее адресном пространстве. В Windows для параллельного выполнения нескольких потоков используется карусельное планирование: каждый поток поочередно получает свой квант времени исполнения, после чего производится переключение контекста процессора на другой активный поток.
В отличие от этого, в задачах реального времени используется приоритетный режим планирования. Менее приоритетные задачи вытесняются более приоритетными. Важнейшую роль в этом играют прерывания. И не только от таймера, а от всей подключенной аппаратуры.
Вот как-то так, если на пальцах...
 
  • Like
Реакции: =AK=

Grem_line

New member
Так как же соотносятся эти Ваши два взаимопротивоположных высказывания:
на одном процессоре нельзя параллельно выполнять задачи. Это как бежать по двум дорогам одновременно одному бегуну.
Для реализации многозадачности не имеет значение число ядер. Для многозадачности нужен лишь таймер
 

rst

Member
Никогда на фирменных ядрах. Это связано с тем, что для обработки событий в них используются очереди. Время реакции не гарантировано!
Извините, но Вы несёте чушь. Какие такие очереди так жизненно необходимы винде? Очереди обработки оконных сообщений (WM_...) что-ли? А с чего Вы решили, что виндовому потоку (thread) они так необходимы? Они нужны только для работы с окнами. И никто не мешает создать thread без окон, назначить ему приоритет выше чем у оконных и работать в нём без очередей.
Да и очереди не так страшны и в RTOS они тоже имеются.
Я согласен с nikolz в том плане, что "при определенных условиях и Windows, и Linux вполне будут работать ка системы реального времени". Всё зависит от требуемого времени отклика.
 

nikolz

Well-known member
Так как же соотносятся эти Ваши два взаимопротивоположных высказывания:
Вы действительно не понимаете или стебаетесь?
------------------------------
В первой фразе говорится о ПАРАЛЛЕЛЬНОСТИ вычислений т е ОДНОВРЕМЕННОМ вычислении
--------------------
Во второй фразе говорится о МНОГОЗАДАЧНОСТИ.
=========================
Попробую объяснить на пальцах специально для двоечников.
Предположим необходимо вычислить 2+2 и 3+3.
сделать это можно двумя способами
1) Написать одну программу в которой последовательно вычисляется 2+2 и 3+3 и выводится результат
2) Написать две программы A =2+2 и B=3+3.
-----------------
Далее на многозадачной ОС можно запустить две задачи A и В на выполнение.
-------------------
И тут ВНИМАНИЕ двоечников!!!!
если у нас одно ядро
то задачи А и В будут выполнятся последовательно.
чем это выполнение будет отличаться от исполнения одной задачи в варианте 1?
Тем что в одной задаче будет с начало вычислено 2+2 а потом 3+3.
А в многозадачном одноядерном варианте ОС будет периодически переключать процессор на исполнение то A то В.
Это переключение будет по таймеру. Причем выполнение двух задач будет медленнее чем исполнение одной по той причине что при каждом переключении надо сохранять состояние задачи а это ресурсы процессора. Например в винде квант переключения задач 10 мс Вот и будет процессор прыгать с задачи на задачу каждые 10 мс.
---------------------
Очевидно, что МНОГОЗАДАЧНОСТЬ не зависит от числа ядер(процессоров) и может быть реализована на одном.
===========================
ПАРАЛЛЕЛЬНО задачи смогут исполняться лишь при наличии двух ядер
тогда перовое ядро будет вычислять 2+2 а второе 3+3. Они будут работать ПАРАЛЛЕЛЬНО если нет надобности у них обращаться к одной и той же памяти данных.
------------------------------
Таким образом МНОГОПОТОЧНОСТЬ т е параллельное исполнение реализуется лишь на многоядерных процессорах На одноядерном эмитируется МНОГОПОТОЧНОСТЬ последовательным переключением процессора .
Т к оно уже реализовано в ОС и ОС будет тратить процессорное время зазря.
======================
Лекция по повышению компьютерной грамотности закончена. Все свободны.
 
Последнее редактирование:
  • Like
Реакции: kab

kab

New member
одноядерном эмитируется МНОГОПОТОЧНОСТЬ
Всё ок! :)
Только не "эмитируется", а "имитируется". От слова "имитация" - :)
Остальное всё в порядке...
Тем не менее, мне представляется, что дискуссия эта практического выхода не имеет. Вы говорите об одном и том же чуть с разных точек зрения. А у Grem_line определённый опыт за спиной явно тоже имеется. Давайте друг к другу быть добрее...
 
Последнее редактирование:
  • Like
Реакции: =AK=

=AK=

New member
Таким образом МНОГОПОТОЧНОСТЬ т е параллельное исполнение реализуется лишь на многоядерных процессорах
nikolz, вы напрасно спорите. Я понимаю, что вы хотите сказать. Однако существует устоявшаяся терминология, и ваше понимание сути обсуждаемых вещей этой терминологии не соответствует. А то, что говорит Grem_line - соответствует. Не обижайтесь.
 

nikolz

Well-known member
nikolz, вы напрасно спорите. Я понимаю, что вы хотите сказать. Однако существует устоявшаяся терминология, и ваше понимание сути обсуждаемых вещей этой терминологии не соответствует. А то, что говорит Grem_line - соответствует. Не обижайтесь.
Я согласен, что под многопоточностью понимают многозадачность
Но я пытаюсь объяснить что для параллельное вычисление нужно несколько ядер.
А если кто-то считает что параллельно можно вычислять на одном ядре, то это нонсенс, если не безграмотность.
 

nikolz

Well-known member
Информация к размышлению.
Из высказываний по данной теме, а также на основе собственных наблюдений полагаю, что отождествление многопоточности с многозадачностью это распространенное заблуждение особенно среди программистов, для которых компьютер - это черный ящик.
Дело было вечером, делать было нечего...
Поэтому решил изложить свое понимание данного вопроса. Все что изложено ниже основано на моем опыте и знаниях и не содержит копий из инета, т е автор всего что напишу я.
Начнем с многозадачности, так как это понятие появилось до появления понятия потоков.
--------------------
Задача - это совокупность трех элементов исходных данных , вычислительных действий над ними и результата.
Процессор - это техническое устройство которое исполняет вычислительные действия.
Память - это то, что хранит исходные данные и результат и программу.
--------------
В ту пору , когда процессор был размером со шкаф и даже больше и стоил очень дорого и кушал очень много возникла проблема дать к нему доступ многим пользователям. В результате появились многопользовательские системы. В таких системах пользователи через свои терминалы могли вне зависимости друг от друга запускать свою задачу на процессоре.
Но если это делать в однозадачной системе, то очередному пользователю пришлось бы ждать когда закончится задача предыдущего.
Что бы решить эту проблему была создана многозадачная система IBM которая выделяла для каждой задачи определенный квант времени для ее исполнения. Т е вне зависимости от действительной сложности задачи ей выделялся фиксированный квант.
 

nikolz

Well-known member
С появлением многозадачности возник вопрос защиты задач и прерывание зацикливания в них из-за ошибок или по злому умыслу а также защита системы от взломщиков.
---------------------------
В результате появился специальный механизм - доп разряд в счетчике команд, который управлялся автоматически и переключал память на специальную область не доступную простым смертным задачам - это режим супервизора.
На микропроцессорах Intel он появился на 386 процессоре.
--------------------------------
Позже появились доп разряды - регистр страниц, который обеспечил возможность выделять каждой задачи отдельную область памяти и тем самым защитить задачи друг от друга.
============================
Многопоточность.
Шло время шкафы процессоров стали меньше и дешевле , а память была большой и дорогой.
Стали ставить несколько процессоров, которые могли работать одновременно, но использовали общую память.
В то время появились такие понятия (т е железо) транспьютеры и кластеры.
Для простых смертных появилось понятие многопоточность.
Поток - это вычислитель , который обрабатывает некоторые данные и получает результат.
Если у нас одна задача и один процессор, то понятия задача и поток суть одно и тоже.
Но если у нас несколько процессоров, то одна задача может решаться параллельно на нескольких ядрах либо каждая из нескольких задач будет решаться на своем ядре.
--------------------
Приведу отвлеченный пример.
Предположим у нас есть 10 кранов с водой и 10 бочек . И у нас 10 задач - наполнить водой каждую бочку из отдельного крана.
Если у нас один шланг - то в каждый момент времени мы можем подключить его лишь к одному крану и заполнять лишь одну бочку.
Это и есть Многозадачность и Однопоточность.
Но если у нас 10 шлангов то мы можем заполнять 10 бочек одновременно.
Это и есть Многозадачность и Многопоточность.
Конец.
 

Grem_line

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

Grem_line

New member
Все-таки, если оставить терминологические споры и вернуться к вопросу топикстартера:
Требуется сделать так, чтобы светодиод мигал (или делалось еще что-либо на фоне работы Web-сервера).
Для этого есть самый простой путь, если ESP работает под управлением RTOS.
Если мы хотим, чтобы это работало на одном вычислительном ядре, нужно выполнить два условия:
1) - Использовать такую функцию delay(), которая не заставляет процессор впустую молотить пустые циклы заданное время, а отложит выполнение текущей задачи на заданное время с переключением на другую. Обычно в RTOS такая функция называется taskDelay().
2) - Запустить процедуру, содержащую цикл мигания светодиода, как отдельную задачу (по сути-поток).
Для этого в некоторых RTOS используется процедура taskSpawn(), в freeRtos это xTaskCreate().
Так как само включение/выключение светодиода занимает наносекунды, то лучше запускать задачу в максимальном приоритете. Для таких RTOS, как например vxWorks, самым высоким является приоритет 0. Чем больше величина, тем ниже приоритет задачи. В freeRTOS вроде-бы наоборот.

Но только нужно, чтобы ESP8266 работал под freeRTOS. Я читал, что есть такие версии. Но та, которая идет для Arduino не годится. ESP32 - может.
 
Сверху Снизу