Por que eu deveria saber programação simultânea?

17

A programação simultânea é bastante difícil para mim: até olhar para um slide básico parece desafiador para mim. Parece tão abstrato.

Quais são os benefícios de conhecer bem os conceitos de programação simultânea? Isso me ajudará na programação seqüencial regular? Sei que há uma satisfação em entender como nossos programas funcionam, mas o que mais?

Adel
fonte
3
Eu acho que é meio complicado, mas pode ficar meio complicado se você editar todas as coisas pessoais (embora a programação simultânea seja bastante difícil para todos ) e pedir os méritos técnicos concretos dos conceitos.
yannis
1
Os benefícios devem ser bastante óbvios. Você pode escrever programas que possam tirar proveito de todos os aprimoramentos de desempenho disponíveis por meio da divisão de trabalho que a programação simultânea oferece. Não é fácil para ninguém. Hoje é um conceito muito desafiador.
Rig
3
Não podemos ajudá-lo a obter motivação para aprender alguma coisa, mas a pergunta geral sobre por que alguém deve saber sobre concorrência está no tópico o suficiente.
2
Eu sei programação simultânea. Eu posso dizer que o slide que você fornece não ajuda a entender. Em vez disso, vá a uma festa com filósofos do jantar .
Mouviciel 21/10
1
Relaxe, até os melhores acham difícil: informit.com/articles/article.aspx?p=1193856
SK-logic

Respostas:

32

Aqui está uma motivação rápida e fácil: Se você quiser código para qualquer coisa, mas os sistemas menores, mais fracos, você vai estar escrevendo código concorrente.

Deseja escrever para a nuvem? As instâncias de computação na nuvem são pequenas. Você não tem grandes, você tem muitos pequenos. De repente, seu pequeno aplicativo da Web é um aplicativo simultâneo. Se você o projetou bem, pode simplesmente lançar mais servidores à medida que ganha clientes. Caso contrário, você precisa aprender como, enquanto sua instância tem sua carga média vinculada.

OK, você quer escrever aplicativos de desktop? Tudo tem uma CPU com um ou mais núcleos. Exceto as máquinas menos caras. E as pessoas com as máquinas menos caras provavelmente não vão se interessar pelo seu software caro, pois não?

Talvez você queira fazer desenvolvimento móvel? Ei, o iPhone 4S tem uma CPU de núcleo duplo. O resto não ficará muito para trás.

Videogames? O Xbox 360 é um sistema com várias CPUs e o PS3 da Sony é essencialmente um sistema com vários núcleos.

Você simplesmente não pode se afastar da programação simultânea a menos que esteja trabalhando em problemas pequenos e simples.

Atualização de 2016 : a iteração atual do Raspberry Pi de US $ 35 é construída em torno de um sistema quad-core em um chip destinado a telefones celulares. Avanços dramáticos na IA foram feitos em parte devido à disponibilidade de placas gráficas de ponta como mecanismos de computação paralelos.

ObscureRobot
fonte
1
Embora eu concorde em princípio, dizer isso Everything has a dual-or-more-core-CPU. Except the least expensive machines.parece um pouco absurdo. Muitas pessoas têm máquinas de núcleo único, não porque seja barato, mas porque estão satisfeitas com o que têm e não vêem necessidade de atualizar. Dito isso, pensar em termos de simultaneidade também ajudará o agendador em um sistema de núcleo único; portanto, não é um esforço desperdiçado em qualquer lugar em que você possa assumir a multitarefa preventiva (que é sobre todos os ambientes de multitarefa com os quais os desenvolvedores entrarão em contato, nos dias de hoje).
um CVn
1
ok - isso é um exagero, mas o novo hardware tende a ser predominantemente multinúcleo. Não vejo isso indo embora. Portanto, se você é um estudante hoje pensando no trabalho que fará profissionalmente no futuro, é seguro assumir que você estará trabalhando em sistemas multicore.
precisa saber é o seguinte
Pergunto-me se eu não concordar com a sua resposta, tanto quanto você discordar com o meu lol;)
1
Do jeito que eu li, existe um núcleo de semelhança com o que estamos dizendo, @ acidzombie24. Estou dizendo que um desenvolvedor deve saber como lidar com a simultaneidade, porque ela estará em todo lugar. Você está dizendo que não precisa ser bom em programação simultânea, contanto que evite as armadilhas dos sistemas concorrentes :)
ObscureRobot
Concordo que é muito útil saber sobre simultaneidade, mas discordo que você só pode se afastar por "pequenos problemas simples". Você pode evitar muito a concorrência, mesmo em sistemas não triviais, por exemplo, se confiar nas estruturas e servidores de aplicativos existentes. Depois que a infraestrutura estiver instalada, posso ser um desenvolvedor júnior que cria novos serviços para um aplicativo Web e não sei quase NADA sobre simultaneidade ou paralelismo.
Andres F.
21

De 1970 a 2002, os processadores dobraram de velocidade a cada 18 meses. Portanto, como programador, tudo o que você precisava fazer era esperar e seu programa seria mais rápido. O problema é que, por volta de 2002, as regras foram alteradas. Agora eles não estão fabricando processadores rápidos maiores, mas sim processadores mais lentos menores, mas os colocando em grupos. O computador em que estou trabalhando agora tem 4 núcleos e existem chips com até 8 núcleos (e 4 threads por núcleo). Em breve teremos chips com muito mais núcleos.

Portanto, se você escrever um programa que não é de todo simultâneo, descobrirá que está usando 1 núcleo ou thread, mas o restante da CPU está lá, sem fazer nada. Portanto, se você tiver 16 núcleos, 1 estará executando seu programa e os outros 15 estarão lá!

O problema com a simultaneidade é que não é determinístico. Ou seja, você não sabe exatamente em que ordem os diferentes threads farão as coisas. Tradicionalmente, os programadores tentam resolver isso usando bloqueios e coisas do gênero. Isso levou a muita dor. Ter alguma forma de estado mutável que mais de um thread possa acessar livremente geralmente é uma fórmula para dor e heisnebugs!

Ultimamente, a tendência tem sido mudar para linguagens funcionais que controlam rigidamente o estado mutável. Existem duas maneiras básicas pelas quais as linguagens funcionais lidam com a simultaneidade. A primeira é usando a passagem de mensagens. Isso é melhor mostrado por Erlang. Em Erlang, em geral, não há estado compartilhado entre processos. Eles se comunicam não compartilhando memória, mas minhas mensagens que passam. Isso deve fazer sentido para você, como estamos fazendo agora. Estou enviando esta informação para você, enviando uma mensagem, não lembrando-a do meu cérebro! Ao mudar para a mensagem que passa, a maioria dos erros de bloqueio simplesmente desaparece. Além disso, as mensagens podem ser transmitidas pela rede e dentro de um nó.

O outro método é o STM, que significa Memória Transcricional de Software. Está presente no clojure e Haskell (e outros). No STM, a memória é compartilhada, mas as alterações só podem ser feitas através de uma transação. Como o pessoal do banco de dados descobriu tudo isso na década de 1970, é muito fácil garantir que acertemos.

Na verdade, simplifiquei um pouco mais, Clojure e Haskell podem passar a mensagem e Erlang pode fazer STM.

Isenção de responsabilidade Eu sou o autor de Programming Web Services with Erlang , que sairá no lançamento antecipado nas próximas semanas.

Zachary K
fonte
1
@ Zachary K: existem abordagens que combinam linguagens funcionais com linguagens nativas, para que partes intensivas em computação sejam implementadas na linguagem nativa, mas fornecem interfaces que podem ser consumidas por um servidor escrito em linguagem funcional?
rwong
Não tenho 100% de certeza, mas Clojure e Scala existem na JVM; é por isso que eu começaria. Talvez dê uma olhada na estrutura Akka. Eu não o usei, mas ouvi uma conversa sobre Akka há um tempo e parece que pode ser bem legal. Por enquanto, estou fazendo Erlang e Javascript, que estão ocupando a maior parte do meu tempo!
Zachary K
1
@rwong: O .NET permite que os programadores usem C # ou outras linguagens não funcionais para algumas partes de seus aplicativos e F #, uma linguagem funcional, para outras.
Kevin - Restabelece Monica
5

Porque a concorrência pode explodir na sua cara quando você espera menos ...

fortran
fonte
4
Você está em
8
A simultaneidade é a nova Inquisição espanhola [/ python] [como em: ninguém espera ...]
ObscureRobot
1
@ObscureRobot duas vezes mais engraçado! (a explicação não era necessário :-P)
fortran
4

A primeira regra da programação simultânea é "É difícil". A segunda regra da programação simultânea é "It. Is. Difícil" .. !!

Sério, porém, existem duas abordagens comuns para programação simultânea, multiencadeamento e multiprocessamento. O multiprocessamento é o mais fácil de entender, pois significa apenas ter várias instâncias de um processo em execução para realizar uma tarefa. É bastante fácil de fazer em sistemas baseados em Unix através de chamadas para bifurcação / junção, mas não tão fácil em sistemas Windows.

A multithreading é provavelmente a abordagem que a maioria das pessoas pensa ao falar sobre simultaneidade. Não é difícil iniciar vários threads em um aplicativo, mas o diabo está nos detalhes. Você precisa coordenar o compartilhamento de dados entre o encadeamento (geralmente usando bloqueios), o que pode levar a um conflito ou a dados em um estado inválido. Você também precisa entender como se comunicar entre threads usando conceitos como semáforos, variáveis ​​condicionais, etc.

A vantagem de tudo isso é que, depois de entender, você poderá utilizar o hardware subjacente de maneira mais eficaz. Atualmente, é praticamente a norma para um processador ter múltiplos núcleos. Ao utilizar a programação simultânea, você pode fazer com que esses núcleos funcionem para você, e seu aplicativo terá uma melhoria na velocidade.

A desvantagem é que você deve começar a pensar em como você dividirá seu aplicativo em pequenas partes que podem ser executadas em threads diferentes. Isso é muito mais difícil do que parece. Além disso, soluções altamente simultâneas podem ser estranhas ao teste de unidade, pois a ordem de execução é menos determinística.

Atualmente, a maioria dos idiomas é enviada com uma abstração sobre a maioria das primitivas simultâneas para tornar a vida um pouco mais fácil. Por exemplo, o .NET 4 é fornecido com a Task Parallel Library, que facilita a vida. Em Java, eles têm o pacote Concurrency .

Sean
fonte
1
Recebe ordens de magnitude se você fugir dos bloqueios o mais rápido possível. Use STM ou atores e tudo o que você disse desaparece. Claro que isso significa mudar do Java para linguagens como Scala, Erlang ou Clojure. (embora eu diria que esta é também uma coisa boa)
Zachary K
@ Zachary: Pode ser uma coisa boa, mas se você trabalha em uma loja .NET, por exemplo, não é prático. O STM pode ser uma opção no futuro, mas no momento não é uma opção nos idiomas convencionais.
Sean
O Clojure é executado em .net e há F #. Eu apostaria que também existem implementações STM para C #.
Zachary K
3

Recentemente, tive uma tarefa muito interessante a ser realizada, na qual o multiprocessamento me salvou. Eu basicamente tive que fazer muitas solicitações para alguns servidores separados, lidando com quantidades muito pequenas de dados, mas com muitas solicitações.

Trabalhando com PHP, fiz as coisas da maneira antiga, e o melhor tempo que obtive após algumas horas de trabalho resultou em ~ 120 segundos para executar um determinado teste (muitos pedidos + atraso na rede + sem assíncrono)

Mas isso não foi o suficiente em comparação com o que eu precisava, e depois de falhar miseravelmente com o multiprocessamento de PHPs, mudei para Python.

Depois de algumas horas, eu tive um script de multiprocessamento Python em execução que foi executado em 20 segundos e depois de um pouco de brincadeira com os tempos limite e não. de threads a serem usados, reduzi para ~ 10 segundos .

Isso era para um site escrito 100% em PHP, exceto um único script Python de 100 linhas. E a coisa toda está funcionando perfeitamente.

Minha conclusão seria que, mesmo que isso não o ajude no dia a dia, você pode encontrar situações em que conhecer pelo menos o básico da programação simultânea o ajudará bastante.

Boa sorte e feliz codificação!

PS: Não estou tentando bash o PHP, mas o PHP simplesmente não era a ferramenta certa para o trabalho em questão.

PS2: Conhecer uma nova tecnologia ou uma nova maneira de fazer as coisas pode abrir as portas para um novo mundo de possibilidades.

Vlad Preda
fonte
2

Se você desenvolve algum tipo de desenvolvimento web, a concorrência entra em ação, pelo menos na maioria dos idiomas. Por exemplo, eu uso o spring para desenvolvimento da web e cada nova solicitação entra como seu próprio encadeamento. Portanto, se qualquer solicitação acabar acessando um objeto compartilhado, onde o estado pode ser alterado de uma variável, a simultaneidade é um fator muito importante e deve ser levado em consideração. Caso contrário, os dados podem ser editados de maneiras imprevisíveis e pode resultar em corrupção de dados. Não é essencial conhecer todos os detalhes sobre simultaneidade, mas aprender partes de cada vez é importante para entender melhor a programação de aplicativos da Web; se você estiver trabalhando em aplicativos de desktop, talvez não seja tão importante, a menos que você precise executar vários threads

programmx10
fonte
-1

Aprenda a visão dos sistemas operacionais. Ler o código fonte dos agendadores e drivers de dispositivo ajudará; eles são definitivamente concorrentes.

jj1bdx
fonte
2
A simultaneidade para programadores geralmente usa seus próprios programas em execução em várias instâncias.
Tentei enfatizar que você não pode escrever seu próprio programa simultâneo de qualquer maneira sem conhecer os detalhes do algoritmo de agendamento do kernel do sistema operacional.
Jj1bdx 3/11
Por que não? Se você usar os mecanismos de bloqueio corretamente, o algoritmo de agendamento do SO não é importante.