Baixe o app para aproveitar ainda mais
Prévia do material em texto
O paradigma concorrente de forma distribuída é uma ótima opção para agilizar o processamento de tarefas, visto que os processos não dependerão de um único recurso. No entanto, o uso de múltiplos processadores (ou múltiplas máquinas) traz alguns problemas, sendo de extrema importância fazer uma análise preliminar para garantir que essa é a melhor solução para cada caso. Em alguns sistemas alguns processos podem ocorrer simultaneamente, proporcionando uma melhor experiência ao usuário devido à maior agilidade no processamento. No entanto, dependendo das instruções que estejam sendo executadas, elas podem conflitar e trazer resultados errôneos, como é o caso das Race Conditions. É contraindicado, por exemplo, compartilhar variáveis mutáveis entre threads sem realizar a devida sincronização. Exemplo: Em um cenário onde 2 processos são executados em núcleos diferentes e compartilham a mesma variável X. O valor inicial de X é 100 e essa variável não pode ser negativa. Os dois processos começam a ocorrer em paralelo, ambos subtraindo 100 do valor de X. Processo A: Verifica valor inicial de X (=100) Processo B: Verifica valor inicial de X (=100) Processo A: Subtrai 100 Processo B: Subtrai 100 Resultado: X = -100 (Quebra da condição X>0) Esse é um tipo de inconsistência que pode ser trazido num sistema a partir do uso do paradigma concorrente distribuído. Nesse tipo de situação o ideal seria que o processo B só começasse a ser executado a partir do final do processo A. Ou então deveria haver uma sincronização entre os dados para garantir a consistência do resultado. No Java, por exemplo, é possível evitar esse tipo de problema de sincronização utilizando a palavra reservada "synchronized". Ela bloqueia todos outros processos(threads) que estejam sendo realizados enquanto completa uma instrução crítica, agindo como single-threaded. Após realizá-la, ela desbloqueia as demais threads e o processamento continua sendo realizado como multi-threaded e com os dados sincronizados. Na programação concorrente também é possível encontrar problemas como o deadLock, no qual um processo fica bloqueado porque depende de um recurso que outro processo está utilizando e vice versa(em uma dependência circular). Também temos o LiveLock, no qual o processo muda constantemente seu estado, mas continua a bloquear um recurso que precisa ser utilizado por outro processo, entrando em uma espécie de loop. Tanto o DeadLock, quanto o LiveLock podem resultar em um problema chamado "Starvation", que ocorre quando a CPU fica bloqueada e não dá vazão dos processos. É possível evitar esse tipo de problema utilizando um algoritmo para priorizar os processos que estão parados há mais tempo e aumentar sua prioridade para alocação de recursos. Apesar de não ser algo trivial, em alguns sistemas isso é necessário para evitar possíveis problemas gerados pela concorrência. O paradigma concorrente de forma distribuída traz muitos benefícios, mas também muitos problemas. Infelizmente, desenvolver um sistema que seja imune aos problemas de concorrência(thread-safe) não é trivial, mas ao pensar em fazê-lo, é imprescindível antecipar os problemas e implementar estratégias para evitá-los.
Compartilhar