Em um PC (um SO, é claro), qualquer programa C se torna indeterminista em termos de tempo. Por exemplo, um loop leva entre 1,2 e 1,3 segundos, dependendo de "quão rápido estou movendo outra janela". Isso ocorre porque o sistema operacional faz com que os processos (ou threads) compartilhem o poder de processamento.
No que diz respeito aos RTOSs (em um sistema incorporado), quando escrevemos um aplicativo multithreading, acho que o mesmo acontece dependendo de quantos threads estão sendo executados simultaneamente.
Não tenho instrumentos para testar isso com precisão em um sistema incorporado. Assim, eu queria perguntar. Minha preocupação é razoável ou estou perdendo algo muito fundamental?
EDIT : vou dar um exemplo. temos task1 (leva 10 ms) e task2 (leva 20 ms). Eles começaram ao mesmo tempo em dois segmentos separados. Minha afirmação (também preocupante, não tenho certeza) é que a tarefa1 leva mais de 10ms, porque eles compartilham o poder de processamento da tarefa2.
Respostas:
Não é verdade que as tarefas em um RTOS são automaticamente determinísticas, mas é possível colocar restrições muito mais rígidas quando e com que frequência as tarefas são executadas. Um RTOS geralmente fornece prioridades rígidas para tarefas; a qualquer momento, a tarefa pronta com a maior prioridade está em execução. O autor do código também tem controle total sobre o conjunto de tarefas em execução; você pode razoavelmente esperar que não haja tarefas em segundo plano de alta prioridade que possam interromper seu código para, por exemplo, trocar dados para o disco, a menos que você os tenha gravado.
Além disso, alguns RTOS oferecem multitarefa cooperativa. Ao contrário da multitarefa preventiva, com a multitarefa cooperativa, uma tarefa continuará sendo executada até que voluntariamente desista do controle da CPU.
fonte
NÃO!
Se isso acontecer, não será um sistema operacional de tempo real (RTOS).
A resposta curta é que a definição de um RTOS não tem nada a ver com multitarefa ou prioridade. Simplesmente todas as tarefas têm garantias de tempo .
O restante do que você considera serem características de um RTOS (priorização, conclusão de tarefas etc.) são meras consequências (ou recursos) da construção de um sistema em que as tarefas devem terminar dentro do intervalo de tempo especificado.
A tarefa multitarefa em um RTOS é conceitualmente mais simples do que em um SO de tempo leve, pois muitos dos casos complicados de borda não são permitidos.
fonte
Um RTOS geralmente não garante a taxa de transferência , mas permite garantir a latência .
Isso geralmente é alcançado por um sistema prioritário, como aqui no FreeRTOS:
Suponha que você tenha uma tarefa de prioridade 1 que leva 10ms para manipular um evento, uma tarefa de prioridade 2 que leva 100ms para manipular um evento diferente e uma tarefa de prioridade 3 em segundo plano. Se você espera obter um evento de prioridade 1 no máximo a cada segundo, pode dizer que o pior caso para lidar com um evento de prioridade 2 é 10 ms + 100 ms. A tarefa de prioridade 3 pode ser desacelerada arbitrariamente pelos eventos, mas você não se importa - porque é de baixa prioridade.
fonte
Prefiro que este seja um comentário, mas são necessários muitos caracteres. De qualquer forma, ozgur, a julgar pelas perguntas em suas respostas aos comentários, você parece estar perdendo o ponto de que não pode simplesmente dizer que meu tópico demora tanto para ser executado e espera que ele funcione magicamente em conjunto com outros tópicos, tudo graças ao sistema operacional. Você precisa projetar seus threads e analisá-los para obter o pior desempenho possível. Se o pior caso não atender aos seus requisitos, você precisará reprojetar seus threads.
Portanto, em vez de simplesmente dizer que o segmento 1 leva 10 ms para ser concluído e o segmento 2 leva 20 ms, você também deve dizer que o segmento 1 deve ser executado a cada 15 ms. o encadeamento 2 deve ser executado a cada 40 ms. o thread 3 deve executar a cada 500 ms, o threadN deve executar a cada 1500 ms. Em seguida, você aloca tempo para quanto tempo cada thread pode levar para concluir no pior cenário. Você reúne tudo isso, identifica os piores cenários possíveis e precisa garantir que cada thread atenda aos requisitos de tempo. Essa análise também é onde você identifica se alguns encadeamentos precisam ter prioridade mais alta que outros para atender aos requisitos de tempo.
Por exemplo, o encadeamento5 em execução é interrompido pelo encadeamento 4, que é interrompido pelo encadeamento 3, que é interrompido pelo encadeamentoN, pode ser um dos piores cenários. Você coloca tudo isso em uma linha do tempo e verifica se, mesmo no pior cenário, cada encadeamento atende aos seus requisitos de tempo. Você pode garantir que os encadeamentos concluam esse cenário de pior caso de maneira determinística usando o planejador e as prioridades em um sistema operacional em tempo real. Esse determinismo é o que contribui para um sistema operacional em tempo real.
Se você criar threads com a mesma prioridade, perderá parte (se não todos) desse determinismo, pois o planejador pode estar livre para escolher o segmento que deseja executar a seguir.
Em um sistema operacional como o Windows, você não apenas pode especificar quando cada thread será executado, como também não pode garantir que seu aplicativo esteja sendo executado a qualquer momento. O sistema operacional pode interromper seu aplicativo e executar algum serviço em segundo plano sempre que desejar. Em outras palavras, não há determinismo. Portanto, o Windows não é um sistema operacional em tempo real. Embora, se seus requisitos de tempo forem grandes, como (o thread1 é executado a cada 10 segundos, o thread2 é executado a cada 15 segundos), você pode essencialmente tratar o Windows como um sistema operacional em tempo real, desde que você responda pelo problema e aproximadamente a cada 10 ou 15 segundos (mais ou menos algumas centenas de milissegundos e uma janela perdida ocasional) é bom o suficiente.
fonte
Embora outras respostas tenham declarado que no "mundo real" seu cenário não é possível, para poder responder à sua pergunta, precisamos criar um sistema hipotético .
Nosso sistema consiste em uma arma que atira bolas a uma velocidade constante, duas caixas que "pegam" as bolas e avançam um passo com cada bola apanhada. A arma pode ser trocada para disparar em uma das caixas, mas perde uma bola cada vez que é trocada. A primeira caixa precisará de 1000 etapas (bolas) para chegar ao fim e a caixa 2 precisará de 2000.
Cenário 1 (tarefas uma após a outra):
- a arma dispara 1000 bolas na caixa 1, alterna (custa 1 bola) e dispara 2000 bolas na caixa 2, num total de 3001 bolas .
Cenário 2 (tarefas "simultâneas"):
- a arma atira 5 bolas em uma caixa, alterna e atira 5 bolas na outra caixa para dar a aparência de simultaneidade . O custo de troca é de (1000/5 x 2 =) 400 bolas. Assim, depois de atirar 2400 bolas, a caixa 1 alcançará seu fim e a caixa 2 precisará de 1000 bolas adicionais para alcançá-lo, totalizando 3400 bolas .
Aplicando esses resultados ao seu cenário, a Tarefa 1 e a primeira metade da Tarefa 2 seriam concluídas após 24 ms, e a segunda metade da Tarefa 2 seria concluída em 10 ms adicionais por um total de 34ms. Isso mostra claramente que o tempo necessário para concluir as tarefas aumenta devido ao tempo perdido na alternância entre tarefas . Esses resultados também são equivalentes à Tarefa 1, que leva 12ms, e à Tarefa 2, que leva 22ms, para ser concluída.
fonte