Assíncrono vs Multithreading - Existe alguma diferença?

133

Uma chamada assíncrona sempre cria um novo thread? Qual é a diferença entre os dois?

Uma chamada assíncrona sempre cria ou usa um novo thread?

A Wikipedia diz :

Na programação de computadores, eventos assíncronos são aqueles que ocorrem independentemente do fluxo principal do programa. Ações assíncronas são ações executadas em um esquema sem bloqueio, permitindo que o fluxo do programa principal continue processando.

Eu sei que chamadas assíncronas podem ser feitas em threads únicos? Como isso é possível?

Ted Smith
fonte
1
O JavaScript não possui threads, mas possui chamadas de método assíncronas.
Ajedi32
1
Qualquer sistema em que um processo gerencia vários subprocessos, o processo de controle pode fornecer operação assíncrona dos subprocessos. No caso de JavaScript, o navegador fornece o fluxo de computação. Quando alguma função faz uma chamada assíncrona, o navegador pode armazenar o contexto dessa função. Agora, o mesmo encadeamento do navegador pode mudar de contexto para retomar a execução de outra função. Enquanto nos programas tradicionais multithread, um thread executando um bloco de funções para permitir que outro thread execute uma função diferente. Cada thread executa sua própria função de forma síncrona.
Mike

Respostas:

82

Esta questão é quase geral demais para responder.

No caso geral, uma chamada assíncrona não cria necessariamente um novo encadeamento. Essa é uma maneira de implementá-lo, com um pool de encadeamentos preexistentes ou um processo externo sendo outras formas. Depende muito da linguagem, modelo de objeto (se houver) e ambiente de tempo de execução.

Assíncrono significa apenas que o encadeamento de chamada não fica parado e aguarda a resposta, nem a atividade assíncrona acontece no encadeamento de chamada.

Além disso, você precisará ser mais específico.

Michael Kohne
fonte
7
Então, basicamente, estou certo ao dizer: Multi-threading == Usando vários threads para fornecer benefícios de processamento em tarefas intensivas de processador que são [idealmente] capazes de se beneficiar de vários processadores, além de benefícios em situações assíncronas. Assincronia == um processo que faz tudo, enquanto o estado que chamou o processo não precisa esperar que seja concluído. (Pode não necessariamente usar vários threads para fazer isso - ou seja, outros componentes de hardware podem assumir responsabilidade).
Evan Sevy
6
@ Michael - Você poderia explicar como a programação assíncrona pode acontecer em um único thread com um exemplo?
Kumar Vaibhav
7
@KumarVaibhav - o exemplo mais comum é quando um único thread trabalha nos itens de uma fila (por exemplo, a fila de mensagens do Windows). Se o programa costuma enviar itens para sua própria fila (um padrão comum), o bit de código que envia o item não espera a conclusão da operação, mas apenas retorna. A operação será resolvida oportunamente pelo loop principal.
22813 Michael Kohne
3
Pode haver uma diferença entre como o código é escrito e como é executado. Por exemplo, em C #, posso ter um método que inicia uma tarefa assíncrona, meu método é totalmente assíncrono e pode fazer outras coisas sem aguardar a conclusão da tarefa. No entanto, o CLR também pode decidir alinhar minha tarefa e executá-la de forma síncrona.
Mike
qual thread executa a tarefa esperada? o método marcado com a-sync é executado de forma síncrona até atingir a palavra-chave wait, nesse ponto qual thread executa esta tarefa aguardável?
102

Sempre que a operação que precisa ocorrer de forma assíncrona não requer que a CPU funcione, essa operação pode ser feita sem gerar outro encadeamento. Por exemplo, se a operação assíncrona for E / S, a CPU não precisará aguardar a conclusão da E / S. Ele só precisa iniciar a operação e pode prosseguir para outro trabalho enquanto o hardware de E / S (controlador de disco, interface de rede etc.) faz o trabalho de E / S. O hardware avisa a CPU quando terminar, interrompendo a CPU, e o sistema operacional entrega o evento ao seu aplicativo.

As abstrações e APIs de nível superior frequentemente não expõem as APIs assíncronas subjacentes disponíveis no SO e no hardware subjacente. Nesses casos, geralmente é mais fácil criar threads para executar operações assíncronas, mesmo se o thread gerado estiver apenas aguardando uma operação de E / S.

Se a operação assíncrona exigir que a CPU funcione, geralmente essa operação deve ocorrer em outro encadeamento para que seja verdadeiramente assíncrona. Mesmo assim, será realmente assíncrono apenas se houver mais de uma unidade de execução.

karunski
fonte
1
Bem explicado, obrigado; mas eu tenho uma pergunta aqui. Você mencionou que "Por exemplo, se a operação assíncrona for E / S, a CPU não precisará aguardar a conclusão da E / S. Ela só precisa iniciar a operação". Minha pergunta é quando o programa é de thread único e, na linha de código 3, você chama uma operação de E / S; então, como você pode iniciar a operação na linha 3 e executar a linha 4 sem esperar pela conclusão da operação de E / S ? Para mim, eu tenho que colocar o código na linha 3 em um novo segmento para alcançar a linha 4 para executar sem esperar pela conclusão da operação de I / O [Java pgm perspectiva].
Homem-Aranha
1
o motivo é que, embora a CPU não precise esperar, a CPU aguardará a conclusão da operação de E / S ... Acredito que seu segundo parágrafo é a resposta para minha consulta. Nesse caso, preciso concluir que, em Java, as chamadas assíncronas precisam ser executadas em um encadeamento diferente. Corrija-me se estou errado ou deixe-me saber se eu tenho que colocar um novo SO qn
Homem-Aranha
@spiderman Algumas linguagens, como o Node.js, têm um modelo de programação assíncrona. O idioma e o tempo de execução fornecem recursos internos que permitem que a linha 4 seja executada no mesmo encadeamento, mesmo antes da conclusão da operação de E / S. Isso é obtido pela linha 3, fornecendo um retorno de chamada que o tempo de execução chamará quando o IO for concluído.
jrahhali
@ spiderman talvez ... a função assíncrona do SO simplesmente retorne false ou algo diretamente.
Byeongin Yoon
18

Não, chamadas assíncronas nem sempre envolvem threads.

Eles normalmente iniciam algum tipo de operação que continua em paralelo com o chamador. Mas essa operação pode ser gerenciada por outro processo, pelo sistema operacional, por outro hardware (como um controlador de disco), por algum outro computador na rede ou por um ser humano. Threads não são a única maneira de fazer as coisas em paralelo.

Jason Orendorff
fonte
12

O JavaScript é de thread único e assíncrono. Ao usar o XmlHttpRequest, por exemplo, você fornece uma função de retorno de chamada que será executada de forma assíncrona quando a resposta retornar.

John Resig tem uma boa explicação sobre a questão relacionada de como os temporizadores funcionam em JavaScript .

George V. Reilly
fonte
12

O multiencadeamento refere-se a mais de uma operação acontecendo no mesmo processo. Enquanto a programação assíncrona se espalha pelos processos. Por exemplo, se minhas operações chamam um serviço da web, o encadeamento não precisa esperar até o serviço da web retornar. Aqui usamos a programação assíncrona que permite que o thread não espere que um processo em outra máquina seja concluído. E quando começa a receber resposta do serviço da web, ele pode interromper o thread principal para dizer que o serviço da web concluiu o processamento da solicitação. Agora o thread principal pode processar o resultado.

Murugan Gopalan
fonte
Eu discordaria um pouco. Escrevi um único servidor HTTP encadeado que lidava com várias solicitações simultâneas usando a conclusão de E / S assíncrona. O Async não exige que as coisas aconteçam em vários caminhos de execução, apenas significa que vários fluxos de computação podem se sobrepor. Outra maneira de analisar é que, em um único sistema operacional encadeado, eu posso ter 2 processos em execução "simultaneamente". Do ponto de vista de cada processo, eles estão sendo executados de forma síncrona. No entanto, do ponto de vista do SO, ele está operando assíncrono.
Mike
11

O Windows sempre teve processamento assíncrono desde os tempos não preventivos (versões 2.13, 3.0, 3.1, etc.) usando o loop de mensagens, muito antes de oferecer suporte a threads reais. Portanto, para responder sua pergunta, não, não é necessário criar um encadeamento para executar o processamento assíncrono.

Otávio Décio
fonte
@dmckee - é interessante como diferentes sistemas evoluem de maneiras semelhantes.
Otávio Décio
8

Chamadas assíncronas nem precisam ocorrer no mesmo sistema / dispositivo que o que está chamando. Portanto, se a pergunta for: uma chamada assíncrona exige um encadeamento no processo atual, a resposta é não. No entanto, deve haver um encadeamento de execução em algum lugar processando a solicitação assíncrona.

Thread de execução é um termo vago. Em sistemas de tarefas cooperativas, como os primeiros sistemas operacionais Macintosh e Windows, o encadeamento de execução pode ser simplesmente o mesmo processo que fez a solicitação executar outra pilha, ponteiro de instruções, etc ... No entanto, quando as pessoas geralmente falam sobre chamadas assíncronas , eles geralmente significam chamadas que são tratadas por outro encadeamento, se for intraprocesso (ou seja, dentro do mesmo processo) ou por outro processo, se for interprocesso.

Observe que a comunicação entre processos (ou interprocessos) (IPC) é geralmente generalizada para incluir comunicação entre processos, já que as técnicas de bloqueio e sincronização de dados geralmente são as mesmas, independentemente do processo em que os threads de execução separados são executados.

Mike
fonte
7

Alguns sistemas permitem que você aproveite a concorrência no kernel para alguns recursos usando retornos de chamada. Para uma instância bastante obscura, os retornos de chamada de entrada / saída assíncrona foram usados ​​para implementar servidores de Internet sem bloqueio nos dias de multitarefa sem preempção do Mac System 6-8.

Dessa forma, você tem fluxos de execução simultâneos "no" que programa sem threads, como tal .

dmckee --- gatinho ex-moderador
fonte
5

Assíncrono significa apenas que você não bloqueia seu programa esperando que algo (chamada de função, dispositivo etc.) termine. Ele pode ser implementado em um encadeamento separado, mas também é comum usar um encadeamento dedicado para tarefas síncronas e se comunicar por meio de algum tipo de sistema de eventos e, assim, obter um comportamento assíncrono.

Existem exemplos de programas assíncronos de thread único. Algo como:

...do something
...send some async request
while (not done)
    ...do something else
    ...do async check for results
Milan Babuškov
fonte
2

A natureza das chamadas assíncronas é tal que, se você deseja que o aplicativo continue em execução enquanto a chamada está em andamento, será necessário gerar um novo encadeamento ou, pelo menos, utilizar outro encadeamento que você criou exclusivamente para os propósitos de manipulação de retornos de chamada assíncronos.

Às vezes, dependendo da situação, convém chamar um método assíncrono, mas fazer com que o usuário pareça síncrono (ou seja, bloqueie até que o método assíncrono sinalize que está completo). Isso pode ser alcançado por meio de APIs do Win32, como WaitForSingleObject .

LeopardSkinPillBoxHat
fonte
Isso é verdade em alguns sistemas, mas não em todos. O Unix não exige que você crie ou utilize outro encadeamento, a menos que você chame o kernel de outro encadeamento, que eu suponho que seja uma maneira de ver isso.
Craig S
Isso também não é verdade no Windows. A E / S sobreposta, por exemplo, é assíncrona.
21412 Jason Orendorff