QUOTE (InsolentS @ Jul 31 2014, 04:00)

Недавно был на интервью в одной компании и "застрял" на вопросе про RTOS. После недели поисков ответ так и не был найден..
Условие задачи такое: есть 5 потоков, каждый из них увеличивает в цикле общую переменную count на 1. После завершения работы этих потоков, значение count выводится на экран.
Как же получается 2? (со слов интервьювера, он наблюдал такой эффект в реальном железе). Подсказка от интервьювера: результат не зависит ни от количества потоков, ни от количества итераций в цикле for
Задача имеет чисто алгоритмическое, логическое решение.
Хорошая задачка на индетерминизм в системе конкурирующих процессов. Решается элементарно! Я удивлён, что ещё никто не догадался...
Сначала несколько замечаний:
a) результат не зависит ни от количества потоков (> 2), ни от количества итераций в цикле for (> 2)
b) задача на алгоритм планировщика очевидно (count ничем не защищён), поэтому планируем задачи как нам _надо_ (кстати, в реальном железе такой алгоритм (или стратегия) планировщика вполне возможна)
c) атрибут volatile конечно хорошо помянуть, но совершенно необязательно, поскольку из условия известно, что перед модификацией значение счётчика всегда читается (что эквивалентно volatile):
CODE
LDR reg, count
ADD reg, #1
STR reg, count
отсюда же видно, что операция модификации счётчика неатомарна, а состоит из трёх фаз, каждая из которых может быть прервана. Вот на этом игра с планированием задач и может быть построена.
d) Решение для значения count = 2, легко обобщается для произвольного значения count, от 2 до суммы инкрементов (каждая задача может совершать произвольное число итераций в цикле)
Алгоритмов, естественно, несколько. Например так:
1) Выбираем произвольно две задачи, А и В.
Каждая читает начальное значение счётчика = 0 и
ставится в ожидание на инструкции ADD.
2) Ждём когда завершатся остальные N-2 задач.
Они больше не нужны, на решение не влияют.
3) Задача В инкрементирует регистр (reg = 1) и
ставится в ожидание на инструкции STR.
4) Задача А продолжает работу и ставится в
ожидание на _последней_ итерации _перед_
инструкцией LDR.
5) Задача В исполняет инструкцию STR
(записывает в ячейку count 1) и ставится в
ожидание.
6) Задача А исполняет инструкцию LDR. В
регистре значение = 1. Инкрементирует
значение регистра = 2 и ставится в ожидание
на инструкции STR.
7) Задача В продолжает работу до завершения!
(Блин, наконец-то, надоело!)
8) Задача А исполняет инструкцию STR, записывает
в ячейку count 2. И завершается! (Блин, наконец-то,
ну жуть как надоело!)
------
Уфф... Очевидно, что розыгрышей в планировании вспомогательной В и остальных N-2 задач может быть несколько, соответственно и алгоритмов решения тоже много. 3) можно "растянуть" объединив с STR, так, что бы в итоге получалось 3, 4, ...
P.S. Очевидно, что это вполне практическая задача, такой результат может быть получен (и будет получен! при достаточно большом числе запусков) на практике.
QUOTE (adnega @ Aug 1 2014, 08:59)

Резальтат, равный 2, печатается постоянно или нужно объяснить ситуацию с крайне низкой вероятностью, когда печатается 2 ?
Абсолютное заблуждение. _Все_ возможные (см. выше) результаты равновероятны. Чем 2 хуже 7 или 16?
Сообщение отредактировал AndrewN - Aug 5 2014, 09:52