Цитата(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);
}