|
Хитровывернутый вопрос про RTOS, с интервью.. |
|
|
|
Jul 31 2014, 01:00
|

Местный
  
Группа: Свой
Сообщений: 414
Регистрация: 8-06-06
Пользователь №: 17 897

|
Всем привет! Недавно был на интервью в одной компании и "застрял" на вопросе про RTOS. После недели поисков ответ так и не был найден.. Условие задачи такое: есть 5 потоков, каждый из них увеличивает в цикле общую переменную count на 1. После завершения работы этих потоков, значение count выводится на экран. Код unsigned int count = 0; void thread(void) { unsigned int i; for(i = 0; i < 5; i++) { count++; } }
void main(void) { thread_create(thread, 5); // Создаём 5 экземпляров потока thread и запускаем их thread_join(); // Ждём пока все 5 потоков завершатся printf("%u", count); // Выводим значение count на экран } Внимание вопрос: почему программа печатает 2?? Договорились с интервьювером, что операция count++ состоит из 3х ассемблерных команд: Код LDR reg, count ADD reg, #1 STR reg, count Т.к. переменная count не защищена ни мьютексом, ни критической секцией, самый пессимистичный вариант, который я "раскрутил" выглядит так: Код // начало работы thread1 LDR reg, count // count = 0, thread1.reg = 0 ADD reg, #1 // thread1.reg = 1 // thread1 вытеснен планировщиком, начало работы thread2 LDR reg, count // count = 0, thread2.reg = 0 ADD reg, #1 // thread2.reg = 1 STR reg, count // count = 1 // thread2 завершил работу, управление возвращается к thread1 STR reg, count // count = 1 т.е. в результате один поток делает override результата второго потока и count = 1 после выполнения всех потоков (а не 5, как было бы с мьютексом). Но: хоть один из потоков все равно увеличит count на 1 в этой схеме, т.е. в результате работы программы count будет не меньше, чем 5. Как же получается 2? (со слов интервьювера, он наблюдал такой эффект в реальном железе). Подсказка от интервьювера: результат не зависит ни от количества потоков, ни от количества итераций в цикле for
--------------------
Курильщик даташитов со стажем
|
|
|
|
|
 |
Ответов
|
Aug 4 2014, 21:06
|
практикующий тех. волшебник
    
Группа: Участник
Сообщений: 1 190
Регистрация: 9-09-05
Пользователь №: 8 417

|
Цитата(Lagman @ Aug 4 2014, 00:04)  Планировщик переключает задачи после каждой инструкции!? вести речь о переключении задач бесмысленно. т.к. фаза старта ниток не синхронизируется. в некоторых осях это вообще может не застартовать секундами-минутами-часами-сутками... код в этом плане левый. нет синхронной фазы готовности всех ниток. типичная ошибка начинающих программеров. Начинает сыпаться или странно себя вести, при ударных нагрузках на серваках. Особенно когда на время жизни ниток начинает навешиваться некая логика. Например общая готовность, или там обслуживание клиентов и т.п. вещи... теоретически-гепотетический код. хорошая тема для начала задушевной беседы, и больше ни для чего. результат не определён вообще...
|
|
|
|
|
Aug 5 2014, 07:43
|

Ally
     
Группа: Модераторы
Сообщений: 6 232
Регистрация: 19-01-05
Пользователь №: 2 050

|
Цитата(kolobok0 @ Aug 5 2014, 00:06)  вести речь о переключении задач бесмысленно. т.к. фаза старта ниток не синхронизируется. в некоторых осях это вообще может не застартовать секундами-минутами-часами-сутками... код в этом плане левый. нет синхронной фазы готовности всех ниток. типичная ошибка начинающих программеров. Начинает сыпаться или странно себя вести, при ударных нагрузках на серваках. Особенно когда на время жизни ниток начинает навешиваться некая логика. Например общая готовность, или там обслуживание клиентов и т.п. вещи...
теоретически-гепотетический код. хорошая тема для начала задушевной беседы, и больше ни для чего. результат не определён вообще... Что это за загадочная "синхронная фаза"? Если код основан на POSIX, то можно кое что восстановить. pthread_create создает и устанавливает готовность задач. Поскольку приоритет не указывается, то логично предположить, что он будет равен приоритету задачи main. Рассматриваем что могло быть на реальном железе: До вытеснения тут явно не дойдет. Тик осей редко бывает короче 10 мс. Значит вся работа задач начнется после вызова thread_join Без аргументов thread_join не бывает, возможно это переопределение оригинальной функции и в этой реализации ожидание всех задач производится по очереди с помощью семафоров. Но возможно реализован механизм ожидания маски флагов от всех задач сразу. В любом случае задачи выполнятся последовательно не вытесняя друг друга, поскольку имеют одинаковый приоритет. Случится прерыванию во время выполнения тех задач крайне мала, поскольку все задачи выполнятся менее чем за микросекунду. Но как в thread_join будет идентифицироваться каждая задача? Передачи дополнительных аргументов с уникальными значениями задачам не видно. В процедуре thread_join наверняка произойдет ошибка после того как там попытаются ожидать окончания нескольких неразличимых задач. И тогда произойдет неожиданный выход из thread_join. Далее заход в функцию printf и там возможно где-то ось не на долго переключится на одну из оставшихся активных задач во время ожидания прерывания по готовности чего-то периферийного. Вот тут и успеет какая-то из задач инкрементировать count до прерывания и переключения контекста на драйвер printf. Во всяком случае у меня аналогичный код под MQX работает идеально при любом уровне оптимизации и всегда выдает 25 Код const TASK_TEMPLATE_STRUCT MQX_template_list[] = { /* Task Index, Function, Stack, Priority, Name, Attributes, Param, Time Slice */ { MAIN_IDX, Main_task, 1500, MAIN_ID_PRIO, "Main", MQX_FLOATING_POINT_TASK + MQX_AUTO_START_TASK, 0, 0 }, { TST_TSK_IDX, Test_Task, 1500, MAIN_ID_PRIO, "TestTask", MQX_FLOATING_POINT_TASK, 0, 0 }, { 0 } };
unsigned int count = 0;
LWEVENT_STRUCT lwevg;
/*-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------*/ void Test_Task(unsigned int initial_data) { unsigned int i; for(i = 0; i < 5; i++) { count++; } _lwevent_set(&lwevg, initial_data); } /*-------------------------------------------------------------------------------------------------------------
-------------------------------------------------------------------------------------------------------------*/ void Main_task(unsigned int initial_data) { _lwevent_create(&lwevg, LWEVENT_AUTO_CLEAR);
_task_create(0, TST_TSK_IDX, 1); _task_create(0, TST_TSK_IDX, 2); _task_create(0, TST_TSK_IDX, 4); _task_create(0, TST_TSK_IDX, 8); _task_create(0, TST_TSK_IDX, 16);
_lwevent_wait_for(&lwevg, 1+2+4+8+16,TRUE,NULL); printf("Count =%u \r\n", count); }
|
|
|
|
Сообщений в этой теме
InsolentS Хитровывернутый вопрос про RTOS Jul 31 2014, 01:00 RobFPGA Приветствую!
Скорее всего он "разводил... Jul 31 2014, 09:54 Fat Robot Переменная count не является volatile, поэтому пре... Jul 31 2014, 10:35 wangan Может у него был 8 битный микроконтроллер, а у нег... Jul 31 2014, 12:08 gerber Неправильно реализована функция printf на железке,... Jul 31 2014, 13:42 Mahagam QUOTE (gerber @ Jul 31 2014, 16:42) Непра... Jul 31 2014, 15:03 Lagman 25. Почему? Патамушта! (кооперативная, вытесн... Jul 31 2014, 15:55 InsolentS Прошу прощения, по условиям задачи RTOS вытесняюща... Jul 31 2014, 18:09 ViKo Для начала неплохо бы понять, в какой ОС есть функ... Jul 31 2014, 18:17 InsolentS Цитата(ViKo @ Jul 31 2014, 23:17) Для нач... Jul 31 2014, 18:27 Fedor Нагло врет ваш интервьюер, если поток будет 1 все ... Jul 31 2014, 19:15 DASM 99.9 % дело не вытеснении, на 32 разрядном проце к... Jul 31 2014, 19:57 ViKo Условная ОС не может быть проверена в железе, как ... Jul 31 2014, 20:00 InsolentS Тут дело не в особенностях какого-то конкретного ж... Aug 1 2014, 05:39 ViKo Цитата(InsolentS @ Aug 1 2014, 08:39) Тут... Aug 1 2014, 05:54  andrew_b Цитата(ViKo @ Aug 1 2014, 09:54) А разве ... Aug 4 2014, 06:17 adnega ЦитатаПодсказка от интервьювера: результат не зави... Aug 1 2014, 05:59 ZASADA что возвращает вызываемая функция
void thread(void... Aug 1 2014, 06:28 ViKo Цитата(ZASADA @ Aug 1 2014, 09:28) что во... Aug 1 2014, 06:31 DASM А какой это язык программирования ? Aug 1 2014, 08:25 ZASADA типа с Aug 1 2014, 08:39 InsolentS На работу всё-таки взяли, попробую найти там этого... Aug 2 2014, 04:19 x893 Всё гораздо проще - просто посмотрите дебаггером -... Aug 3 2014, 13:29 InsolentS Цитата(x893 @ Aug 3 2014, 18:29) Всё гора... Aug 3 2014, 18:13  AlexandrY Цитата(InsolentS @ Aug 3 2014, 21:13) Спа... Aug 4 2014, 06:48  psL Цитата(Lagman @ Aug 4 2014, 00:04) Планир... Aug 3 2014, 21:53   AndrewN QUOTE (psL @ Aug 4 2014, 00:53) В реально... Aug 5 2014, 10:04    Mahagam QUOTE (AndrewN @ Aug 5 2014, 13:04) Ключе... Aug 5 2014, 10:09 AndrewN QUOTE (InsolentS @ Jul 31 2014, 04:00) Не... Aug 5 2014, 09:57 AlexandrY Цитата(AndrewN @ Aug 5 2014, 12:31) P.S. ... Aug 5 2014, 10:01  AndrewN QUOTE (AlexandrY @ Aug 5 2014, 13:01) Да,... Aug 5 2014, 10:07   AlexandrY Цитата(AndrewN @ Aug 5 2014, 13:07) Да бр... Aug 5 2014, 10:14    AndrewN QUOTE (AlexandrY @ Aug 5 2014, 13:14) Есл... Aug 5 2014, 10:21  AndrewN QUOTE (AlexandrY @ Aug 5 2014, 13:01) Да ... Aug 5 2014, 10:09   AlexandrY Цитата(AndrewN @ Aug 5 2014, 13:09) Вы ме... Aug 5 2014, 10:19    AndrewN QUOTE (AlexandrY @ Aug 5 2014, 13:19) Мне... Aug 5 2014, 10:27     AlexandrY Цитата(AndrewN @ Aug 5 2014, 13:24) Совер... Aug 5 2014, 10:31      AndrewN QUOTE (AlexandrY @ Aug 5 2014, 13:31) гов... Aug 5 2014, 10:55 Mahagam QUOTE (AndrewN @ Aug 5 2014, 12:31) Хорош... Aug 5 2014, 10:04  AndrewN QUOTE (Mahagam @ Aug 5 2014, 13:04) решен... Aug 5 2014, 10:15   AlexandrY Цитата(AndrewN @ Aug 5 2014, 13:15) Мы же... Aug 5 2014, 10:24    den_po Цитата(AlexandrY @ Aug 5 2014, 14:24) Тик... Aug 5 2014, 12:29   Mahagam QUOTE (AndrewN @ Aug 5 2014, 13:15) Это п... Aug 5 2014, 10:55    AlexandrY Цитата(Mahagam @ Aug 5 2014, 13:55) какое... Aug 5 2014, 11:02    AndrewN QUOTE (Mahagam @ Aug 5 2014, 13:55) Ни од... Aug 5 2014, 11:27     Mahagam QUOTE (AndrewN @ Aug 5 2014, 14:27) Увы, ... Aug 5 2014, 11:37      AndrewN QUOTE (Mahagam @ Aug 5 2014, 14:37) вы то... Aug 5 2014, 12:39       AlexandrY Цитата(AndrewN @ Aug 5 2014, 15:30) Я поп... Aug 5 2014, 12:42        AndrewN QUOTE (AlexandrY @ Aug 5 2014, 16:42) Ну ... Aug 5 2014, 12:50         AlexandrY Цитата(AndrewN @ Aug 5 2014, 15:50) P.S. ... Aug 6 2014, 10:48       AlexandrY Цитата(AndrewN @ Aug 5 2014, 15:39) Ребят... Aug 5 2014, 12:54       Mahagam QUOTE (AndrewN @ Aug 5 2014, 15:39) Неизв... Aug 5 2014, 15:09        AndrewN QUOTE (Mahagam @ Aug 5 2014, 19:09) отсле... Aug 5 2014, 16:06     AlexandrY Цитата(AndrewN @ Aug 5 2014, 14:27) Алгор... Aug 5 2014, 12:26 ViKo Ну, теоретически (практически тоже) можно допустит... Aug 5 2014, 10:28 adnega CODE задача А задача В задача Х
... Aug 5 2014, 12:55 juvf аш 4 страници настучали....
1) а кто пробовал это... Aug 5 2014, 18:05 AndrewN Жаль, что не удалось узнать, что думает экзаминато... Aug 7 2014, 12:35 InsolentS Цитата(AndrewN @ Aug 7 2014, 18:35) Жаль,... Jan 24 2015, 02:52
1 чел. читают эту тему (гостей: 1, скрытых пользователей: 0)
Пользователей: 0
|
|
|