1. Introdução
Aquele que aprendeu a voar não rastejará mais. Mas também não deve haver arrogância em relação a alguém que "não pode voar" em princípio. Ambos são normais. Ambos são respeitados e honrados. Para uma pessoa, é como escolher uma profissão: você, convencionalmente, é piloto ou motorista. Para os mesmos animais, é o mesmo - você é uma águia ou um lobo, ou seja, Ou você voa ou corre (foge) Mas apenas uma pessoa em seus conceitos, categorias, atitudes e pensamentos dotou os personagens de características e desenvolveu sua atitude em relação a eles. Verdade, com nuances. Então, não, provavelmente, é mais honrado e romântico do que a profissão de piloto, mas tentar convencer um caminhoneiro ou projetista de aeronaves disso ?! E aqui é difícil argumentar: há muitos astronautas mesmo agora, e ainda não há uma segunda rainha!
Somos programadores. Talvez em vários graus, mas alguns - com certeza. Isso significa que somos diferentes e também podemos pensar de maneiras diferentes. A afirmação de que um programador apenas pensa consistentemente é tão unilateral, prejudicial e até blasfema, quanto o fato de uma pessoa apenas executar. Ele às vezes - e voa. Alguns, como os pilotos, fazem isso com bastante regularidade, e alguns, como os astronautas, mesmo por meses e continuamente. A ideia de pensamento consistente diminui a habilidade humana. Em algum momento e por um tempo, você pode até acreditar, mas "mesmo assim, muda" - trata-se do fato de que mais cedo ou mais tarde a vida cobrará seu preço.
Asyncio em Python é uma muleta de software que imita, figurativamente falando, o vôo do pensamento paralelo incorreto. Uma espécie de quicando com as mãos acenando. Parece, às vezes, engraçado e desajeitado. Embora em certa situação esta também seja uma saída: você pode simplesmente cruzar a poça e se sujar, mas se a força permitir, então é melhor pular. Mas talvez os programadores não tenham força?
Vamos tentar descartar as "muletas do software" impostas e voar acima da rotina do software. E que não seja um salto, ou talvez não tão alto e longo, mas ainda, especialmente em comparação com muletas, um vôo. Afinal, uma vez Alexander Fyodorovich Mozhaisky (não deve ser confundido com o Tribunal da cidade de Mozhaisky da região de Moscou;) ou os mesmos irmãos Wright superaram várias centenas de metros no ar pela primeira vez. Sim, e os testes de aeronaves modernas começam com uma corrida e uma breve separação da pista.
2. Um exemplo muito simples com assíncio
Começaremos voando em Python. O programa de vôo é simples. Existem aviões (que, no entanto, na versão original das imagens das aranhas, ver [1] ) com nomes nas fuselagens "Blog", "Notícias", "Fórum". Eles decolam ao mesmo tempo. Todos devem voar em um segmento do caminho em um determinado tempo e lançar, digamos, uma bandeira com o número do segmento coberto. Isso deve ser feito três vezes. E só então pousar.
Em Python, um modelo desse comportamento é descrito e, em seguida, simulado pelo código na Listagem 1.
Listagem 1. Código Python para aviões spider
import asyncio
import time
async def spider(site_name):
for page in range(1, 4):
await asyncio.sleep(1)
print(site_name, page)
spiders = [
asyncio.ensure_future(spider("Blog")),
asyncio.ensure_future(spider("News")),
asyncio.ensure_future(spider("Forum"))
]
start = time.time()
event_loop = asyncio.get_event_loop()
event_loop.run_until_complete(asyncio.gather(*spiders))
event_loop.close()
print("{:.2F}".format(time.time() - start))
Os resultados da simulação para tal "vôo" são os seguintes:
Blog 1
Notícias 1
Fórum 1
Blog 2
Notícias 2
Fórum 2
Blog 3
Notícias 3
Fórum 3
3,00
Por que isso é explicado tão detalhadamente no vídeo [1]. Mas nós caras com imaginação e o vôo simultâneo (conforme o cenário - assíncrono) de nossos três “aviões” sem o uso de assíncio vamos nos apresentar de uma forma diferente - a partir de modelos automáticos. Por exemplo, a Listagem 2 mostra o código para um atraso de autômato, um análogo do atraso assíncrono do módulo asyncio, representado pela linha await asyncio.sleep (1) na Listagem 1.
Listagem 2. Código de atraso automático em Python
import time
class PSleep:
def __init__(self, t, p_FSM): self.SetTime = t; self.nState = 0; self.bIfLoop = False; self.p_mainFSM = p_FSM
def x1(self): return time.time() - self.t0 <= self.SetTime
def y1(self): self.t0 = time.time()
def loop(self):
if (self.nState == 0): self.y1(); self.nState = 1
elif (self.nState == 1):
if (not self.x1()): self.nState = 4
O valor de atraso e um ponteiro para o objeto que criou o objeto de atraso são passados pelo construtor de classe. O ponteiro é requerido pela função de controle do processo, que, após remover o atraso, dará continuidade ao processo pai, que estava parado quando foi criado.
A Listagem 3 mostra a contraparte do autômato para o plano spider assíncrono (consulte também a Listagem 1). É muito provável que um ás da programação Python não sonhe com isso, mesmo no mais pesadelo! O código-fonte de quatro linhas cresceu 15 vezes! Não é isso um motivo de admiração pelo código Python típico em geral e asycio em particular, ou, pelo menos, uma prova da vantagem da "tecnologia de corrotina" sobre a programação de autômato?
Listagem 3. Código para uma aranha autômato em Python
# "" "Blog"
class PBSpider:
def __init__(self, name):
self.nState = 0; self.bIfLoop = True; self.site_name = name; self.page = 1;
self.p_mainFSM = b_sleep;
def x1(self): return self.page < 4
def y1(self):
self.bIfLoop = False; automaton.append(b_sleep);
b_sleep.p_mainFSM = blog
automaton[-1].bIfLoop = True;
automaton[-1].nState = 0
def y2(self): print(self.site_name, self.page)
def y3(self): self.page += 1
def y4(self): self.page = 1
def loop(self):
if (self.x1() and self.nState == 0): self.y1(); self.nState = 1
elif (not self.x1() and self.nState == 0): self.y1(); self.y4(); self.nState = 33
elif (self.nState == 1): self.y2(); self.y3(); self.nState = 0
# "" "News"
class PNSpider:
def __init__(self, name):
self.nState = 0; self.bIfLoop = True; self.site_name = name; self.page = 1;
self.p_mainFSM = n_sleep;
def x1(self): return self.page < 4
def y1(self):
self.bIfLoop = False; automaton.append(n_sleep);
n_sleep.p_mainFSM = news
automaton[-1].bIfLoop = True;
automaton[-1].nState = 0
def y2(self): print(self.site_name, self.page)
def y3(self): self.page += 1
def y4(self): self.page = 1
def loop(self):
if (self.x1() and self.nState == 0): self.y1(); self.nState = 1
elif (not self.x1() and self.nState == 0): self.y1(); self.y4(); self.nState = 33
elif (self.nState == 1): self.y2(); self.y3(); self.nState = 0
# "Forum"
class PFSpider:
def __init__(self, name):
self.nState = 0; self.bIfLoop = True; self.site_name = name; self.page = 1;
self.p_mainFSM = f_sleep;
def x1(self): return self.page < 4
def y1(self):
self.bIfLoop = False; automaton.append(f_sleep);
f_sleep.p_mainFSM = forum
automaton[-1].bIfLoop = True;
automaton[-1].nState = 0
def y2(self): print(self.site_name, self.page)
def y3(self): self.page += 1
def y4(self): self.page = 1
def loop(self):
if (self.x1() and self.nState == 0): self.y1(); self.nState = 1
elif (not self.x1() and self.nState == 0): self.y1(); self.y4(); self.nState = 33
elif (self.nState == 1): self.y2(); self.y3(); self.nState = 0
#
b_sleep = PSleep(1, 0)
n_sleep = PSleep(1, 0)
f_sleep = PSleep(1, 0)
# ""
blog = PBSpider("Blog")
news = PNSpider("News")
forum = PFSpider("Forum")
#
automaton = []
automaton.append(blog);
automaton.append(news);
automaton.append(forum);
start = time.time()
# ( event_loop)
while True:
ind = 0;
while True:
while ind < len(automaton):
if automaton[ind].nState == 4:
automaton[ind].p_mainFSM.bIfLoop = True
automaton.pop(ind)
ind -=1
elif automaton[ind].bIfLoop:
automaton[ind].loop()
elif automaton[ind].nState == 33:
print("{:.2F}".format(time.time() - start))
exit()
ind += 1
ind = 0
E aqui está o resultado dos voos automáticos:
Notícias 1
Fórum 1
Blog 1
Blog 2
Notícias 2
Fórum 2
Notícias 3
Fórum 3
Blog 3
3,00
Mas - vamos discutir. O aumento no tamanho do código foi devido a problemas com ponteiros em Python. Como resultado, tive que criar uma classe para cada página, o que triplicou o código. Portanto, é mais correto falar não sobre 15, mas sobre um aumento de cinco vezes no volume. Um "piloto Python" mais habilidoso em programação pode até ser capaz de eliminar essa deficiência.
Mas o principal motivo ainda não são os ponteiros. O código C ++ mostrado abaixo, com total liberdade para trabalhar com ponteiros, possui ainda mais linhas por classe. O motivo é o modelo computacional utilizado, a linguagem de sua descrição e as abordagens para a implementação de algoritmos baseados nele. Figura: 1 mostra um modelo de plano de aranha convencional na forma de diagrama de blocos e um modelo de metralhadora. Você pode ver que externamente e em qualidade esses são modelos diferentes, embora permitam transformações equivalentes. Os autômatos têm estados, mas os diagramas de blocos nem mesmo têm um traço deles. Os autômatos, por definição, operam em tempo discreto, e os diagramas de blocos nem sonham com isso. Tudo isso impõe certas obrigações à implementação do modelo.
A ausência do conceito de tempo discreto é a essência dos problemas do modelo de programação de diagrama de blocos existente, que deve implementar, estritamente falando, irrealizável para ele, ou seja, processos paralelos. Lembre-se de que, para autômatos, uma rede de autômatos, como modelo de processos paralelos (assim como assíncronos), é seu estado natural.
Figura: 1. Modelos automáticos e de diagrama de blocos de um plano de aranha
Porém, mesmo no nível de um processo separado, os modelos têm diferenças que são projetadas na linguagem e na implementação do modelo. Em virtude dessas qualidades, os apologistas de um diagrama de blocos consistente criaram construções de linguagem que, explícita ou implicitamente, tornam possível descrevê-lo de maneira muito compacta. Faça o mesmo for loop ou pelo menos uma sequência implicitamente implícita de execução do operador (ações y1, y2, y3).
Para um fluxograma, você pode listar as ações em uma caixa sem problemas e isso não mudará a natureza sequencial de seu trabalho. Se o autômato substituir as transições nos estados s2, s3 por um ciclo no estado s1, marcando o arco com as mesmas ações, então o significado do algoritmo mudará, uma vez que irá introduzir paralelismo ao seu trabalho. Uma vez que as ações acima devem ser executadas estritamente sequencialmente, isso predeterminou a aparência do modelo do autômato (ver Fig. 1). Um autômato finito é um modelo que não permite "duplipensar".
A falta de tempo discreto nos diagramas de blocos era sua vantagem. Mas agora essa se tornou sua principal desvantagem. Afeta, como pode não parecer blasfemo, e a maneira de pensar. As linguagens sequenciais justificam o pensamento sequencial dos programadores negando-lhes algo mais - paralelo. Isso é o que justifica as construções da programação assíncrona existente, apresentando o conjunto e funcionalidade de operadores de um mesmo pacote asyncio. E é precisamente essa abordagem, argumenta-se, que permite aos programadores familiarizados com programas sequenciais se tornarem assíncronos (quase paralelos).
Mas voltando ao tema do artigo e suas imagens. Queríamos o nosso "avião" e conseguimos! Os voos, ou, mais precisamente, seus resultados visíveis, são um pouco diferentes na aparência, mas completamente indistinguíveis na natureza. Eles podem ser interpretados de tal forma que as bandeiras foram selecionadas e registradas no protocolo em uma ordem diferente, mas os próprios "aviões" voaram como deveriam, ou seja, simultânea e simultaneamente jogaram suas bandeiras. E em que ordem foram registrados - o caso, como dizem, é o décimo. O principal é realizado e cumprido: a sequência e os horários de seu lançamento correspondem ao programa de vôo
O código pode ser reduzido. Então, aparentemente, você pode se limitar ao código de apenas uma classe. Você também pode ocultar o código do loop de evento. Se, ao mesmo tempo, no código-fonte, você abrir o código do compartimento do motor, que está escondido atrás do assíncio e aguardar os operadores, a quantidade de código de autômato provavelmente não será tão assustadora.
3. Sobre os problemas de implementação de autômatos em Python
Detenhamo-nos mais detalhadamente nos problemas que deram origem ao surgimento do código automático. A última coisa a esconder parece até agora monstruosa em comparação com o código-fonte. Mas notemos que a primeira aeronave de Mozhaisky estava longe de ser semelhante à "secagem" moderna, e os primeiros carros não diferiam para melhor de nenhum de seus equivalentes modernos. Deixe-me enfatizar que os problemas do código de autômato apresentado estão amplamente relacionados ao meu entendimento atual da linguagem Python e, talvez, em menor grau, com os recursos da própria linguagem.
No entanto, o primeiro problema está relacionado com a linguagem de descrição do modelo de autômato. Em C ++, isso é resolvido usando meios de linguagem. Não vejo essas possibilidades em Python. Infelizmente, como às vezes dizem agora, pela palavra em tudo. Portanto, o método de implementação de autômatos baseado em operadores de controle da linguagem if-elif-else foi tomado como base. Além disso, lembramos que no CPSU (a), além dos próprios autômatos, memória sombra e espaços de autômato foram introduzidos para a implementação completa do paralelismo. Sem isso, as possibilidades de programação de autômatos são muito limitadas e em muitos aspectos inferiores.
O próximo problema que já mencionamos são os ponteiros. Não há problemas com eles em C ++. No âmbito do CPSU (a), de acordo com o paradigma OOP, foi criada uma classe de autômato básica, a partir da qual classes de autômato aplicadas são geradas, e seus parâmetros podem ser não apenas ponteiros, mas também seus endereços. Tudo isso torna possível descrever e implementar de forma simples, compacta e muito eficiente qualquer tarefa que inclua muitos processos de interação paralela.
A seguir está o código das classes de autômatos C ++ equivalentes ao exemplo considerado. O código de atraso na Listagem 4 é equivalente à linha await asyncio.sleep (1) na Listagem 1. Na forma gráfica, corresponde ao modelo de autômato FAwaitSleep na Figura 1. 1. Tal e somente tal autômato pode ser considerado assíncrono e não irá retardar o fluxo computacional. FSleep na mesma figura corresponde ao operador sleep () usual. É mais simples, mas garante a destruição do modelo de tempo discreto devido à ação de y1 causando o atraso sequencial usual. E isso não serve mais para nada.
Listagem 4. Código de atraso assíncrono
// ( )
#include "lfsaappl.h"
#include <QTime>
class FAwaitSleep :
public LFsaAppl
{
public:
FAwaitSleep(int n);
protected:
int x1();
QTime time;
int nAwaitSleep;
};
#include "stdafx.h"
#include "FAwaitSleep.h"
static LArc TBL_AwaitSleep[] = {
LArc("s1", "s1","x1", "--"), //
LArc("s1", "00","^x1", "--"), //
LArc()
};
FAwaitSleep::FAwaitSleep(int n):
LFsaAppl(TBL_AwaitSleep, "FAwaitSleep")
{
nAwaitSleep = n; time.start();
}
int FAwaitSleep::x1() { return time.elapsed() < nAwaitSleep; }
O código C ++ para o plano-aranha é mostrado na Listagem 5. Esse código é muito mais adequado para seu modelo do que o diagrama de blocos do código Python. Especialmente se compararmos a tabela de transição do autômato e a aparência do gráfico do autômato. Eles são simplesmente formas diferentes de descrever o mesmo conceito abstrato - um autômato. Também mostra como um ponteiro para a classe pai é passado ao criar um atraso (veja a chamada para o método FCall na atividade y1)
Listagem 5. Código para um plano de aranha que simula a leitura de páginas do site
// "".
#include "lfsaappl.h"
class FAwaitSleep;
class FSpider :
public LFsaAppl
{
public:
LFsaAppl* Create(CVarFSA *pCVF) { Q_UNUSED(pCVF)return new FSpider(nameFsa); }
bool FCreationOfLinksForVariables() override;
FSpider(string strNam);
virtual ~FSpider(void);
CVar *pVarStrSiteName; //
FAwaitSleep *pFAwaitSleep{nullptr};
protected:
int x1(); void y1(); void y2(); void y3(); void y4();
int page{1};
};
#include "stdafx.h"
#include "FSpider.h"
#include "FSleep.h"
#include "FAwaitSleep.h"
#include <QDebug>
static LArc TBL_Spider[] = {
LArc("st","s1","--","--"),
LArc("s1","s2","x1","y1"), // x1- <. ; y1-;
LArc("s2","s3","--","y2"), // y2- ;
LArc("s3","s1","--","y3"), // y3-
LArc("s1","st","^x1","y4"), // y4-
LArc()
};
FSpider::FSpider(string strNam):
LFsaAppl(TBL_Spider, strNam)
{ }
FSpider::~FSpider(void) { if (pFAwaitSleep) delete pFAwaitSleep; }
bool FSpider::FCreationOfLinksForVariables() {
pVarStrSiteName = CreateLocVar("strSiteName", CLocVar::vtString, "name of site");
return true;
}
// ?
int FSpider::x1() { return page < 4; }
// create delay - pure sleep (synchronous function) or await sleep (asynchronous function)
void FSpider::y1() {
//sleep(1000);
// await sleep (asynchronous function)
if (pFAwaitSleep) delete pFAwaitSleep;
pFAwaitSleep = new FAwaitSleep(1000);
pFAwaitSleep->FCall(this);
}
void FSpider::y2() {
#ifdef QT_DEBUG
string str = pVarStrSiteName->strGetDataSrc();
printf("%s%d", str.c_str(), page);
qDebug()<<str.c_str()<<page;
#endif
}
void FSpider::y3() { page++; }
void FSpider::y4() { page = 1; }
Não há código que implemente as funções do chamado loop de eventos. Simplesmente não há necessidade disso. suas funções são desempenhadas pelo núcleo do ambiente CPSU (a). Ele cria objetos e gerencia sua execução paralela em tempo discreto.
4. Conclusões
A brevidade nem sempre é irmã do talento e, às vezes, também é um sinal de falta de língua. É verdade que é difícil distinguir um do outro ao mesmo tempo. O código Python geralmente será menor que o código C ++. Mas isso é típico para casos simples. Quanto mais complexa for a solução, menor será essa diferença. No final, até a complexidade da solução é determinada pelos recursos do modelo. Um modelo de autômato é muito mais poderoso do que um diagrama de blocos.
Os autômatos e a paralelização são, antes de tudo, meios muito eficazes de resolver problemas de complexidade, combatê-la, e não tanto um meio de aumentar a velocidade de um programa. Como tudo isso é um modelo de autômato, o paralelismo é difícil de implementar em Python, então, apesar de todos os seus chips, baterias e muito mais, é difícil para mim balançar em sua direção. Eu prestaria mais atenção ao ambiente C ++ e não faria uma introdução muito justificada das mesmas corrotinas nele. Este modelo é temporário e o motivo de sua implementação é amplamente forçado. E o que faremos com essa "muleta" quando o problema de escolha de um modelo paralelo for resolvido?
Portanto, desculpe, mas minha preferência ainda está no lado C ++. E se você considerar a área de meus interesses profissionais - sistemas industriais do chamado tempo real difícil "assustador", então eu não tenho escolha como tal. Sim, algum tipo de ambiente, algum tipo de serviço pode ser criado usando Python. É conveniente, é rápido, existem muitos protótipos, etc. etc. Mas o núcleo da solução, seu modelo paralelo, a lógica dos próprios processos são inequivocamente C ++, inequivocamente autômatos. Aqui os autômatos, é claro, são mais importantes e dominam. Mas não co-rotinas :)
Além disso ... Assista ao vídeo [2] , prestando atenção na implementação do modelo de foguete. Sobre ela, a partir do 12º minuto, o vídeo narra. Respeito ao palestrante pelo uso das máquinas :) E para um doce deleite, outra solução de [3]... Está no espírito da programação assíncrona e assíncrona. Na verdade, tudo começou com este exemplo - a implementação de autômatos aninhados em Python. Aqui, a profundidade de aninhamento é ainda maior do que no exemplo detalhado acima. A Listagem 6 mostra o código-fonte e sua contraparte Python autômato. Na fig. 2 é o modelo automático de consumo de chá e a Listagem 7 mostra a implementação C ++ equivalente para VKP (a). Compare, analise, tire conclusões, critique ...
Listagem 6. Lendo e bebendo chá de forma assíncrona em Python
import asyncio
import time
# # Easy Python. Asyncio python 3.7 https://www.youtube.com/watch?v=PaY-hiuE5iE
# # 10:10
# async def teatime():
# await asyncio.sleep(1)
# print('take a cap of tea')
# await asyncio.sleep(1)
#
# async def read():
# print('Reading for 1 hour...')
# await teatime()
# print('...reading for 1 hour...')
#
# if __name__ == '__main__':
# asyncio.run(read())
class PSleep:
def __init__(self, t, p_FSM): self.SetTime = t; self.nState = 0; self.bIfLoop = False; self.p_mainFSM = p_FSM
def x1(self): return time.time() - self.t0 <= self.SetTime
def y1(self): self.t0 = time.time()
def loop(self):
if (self.nState == 0): self.y1(); self.nState = 1
elif (self.nState == 1):
if (not self.x1()): self.nState = 4
class PTeaTime:
def __init__(self, p_FSM): self.nState = 0; self.bIfLoop = False; self.p_mainFSM = p_FSM;
def y1(self): self.bIfLoop = False; automaton.append(sl); automaton[-1].bIfLoop = True; automaton[-1].nState = 0
def y2(self): print('take a cap of tea')
def loop(self):
if (self.nState == 0): self.y1(); self.nState = 1
elif (self.nState == 1): self.y2(); self.nState = 2
elif (self.nState == 2): self.y1(); self.nState = 3
elif (self.nState == 3): self.nState = 4
class PRead:
def __init__(self): self.nState = 0; self.bIfLoop = False;
def y1(self): print('Reading for 1 hour...')
def y2(self): self.bIfLoop = False; automaton.append(rt); automaton[-1].bIfLoop = True; automaton[-1].nState = 0
def loop(self):
if (self.nState == 0): self.y1(); self.nState = 1
elif (self.nState == 1): self.y2(); self.nState = 2
elif (self.nState == 2): self.y1(); self.nState = 33; self.bIfLoop = False
read = PRead()
rt = PTeaTime(read)
sl = PSleep(5, rt)
automaton = []
automaton.append(read); automaton[-1].bIfLoop = True
while True:
ind = 0;
while True:
while ind < len(automaton):
if automaton[ind].nState == 4:
automaton[ind].p_mainFSM.bIfLoop = True
automaton.pop(ind)
ind -=1
elif automaton[ind].bIfLoop:
automaton[ind].loop()
elif automaton[ind].nState == 33:
exit()
ind += 1
ind = 0
Figura: 2. Modelo automático de beber chá
Listagem 7. Lendo e bebendo chá de forma assíncrona em C ++
#include "lfsaappl.h"
class FRead :
public LFsaAppl
{
public:
LFsaAppl* Create(CVarFSA *pCVF) { Q_UNUSED(pCVF)return new FRead(nameFsa); }
FRead(string strNam);
virtual ~FRead(void);
protected:
void y1(); void y2(); void y3();
LFsaAppl *pFRealTime{nullptr};
};
#include "stdafx.h"
#include "FRead.h"
#include "FTeaTime.h"
#include <QDebug>
static LArc TBL_Read[] = {
LArc("s1","s2","--","y1"), // Reading for 1 hour...
LArc("s2","s3","--","y2"), // Call(TeaTime)
LArc("s3","s4","--","y1"), // Reading for 1 hour...
LArc("s4","s5","--","y3"), // sleep(5)
LArc("s5","s1","--","--"), //
LArc()
};
FRead::FRead(string strNam):
LFsaAppl(TBL_Read, strNam)
{ }
FRead::~FRead(void) { if (pFRealTime) delete pFRealTime; }
void FRead::y1() {
#ifdef QT_DEBUG
qDebug()<<"Reading for 1 hour...";
#endif
}
void FRead::y2() {
if (pFRealTime) delete pFRealTime;
pFRealTime = new FTeaTime("TeaTime");
pFRealTime->FCall(this);
}
void FRead::y3() { FCreateDelay(5000); }
#include "lfsaappl.h"
class FTeaTime :
public LFsaAppl
{
public:
FTeaTime(string strNam);
protected:
void y1(); void y2();
};
#include "stdafx.h"
#include "FTeaTime.h"
#include <QDebug>
#include "./LSYSLIB/FDelay.h"
static LArc TBL_TeaTime[] = {
LArc("s1", "s2","--","y1"),// sleep(1)
LArc("s2", "s3","--","y2"),// take a cap of tea
LArc("s3", "s4","--","y1"),// sleep(1)
LArc("s4", "00","--","--"),//
LArc()
};
FTeaTime::FTeaTime(string strNam):
LFsaAppl(TBL_TeaTime, strNam)
{ }
void FTeaTime::y1() { FCreateDelay(2000); }
void FTeaTime::y2() {
#ifdef QT_DEBUG
qDebug()<<"take a cap of tea";
#endif
}
PS
Já depois de escrever o artigo, depois de ler a tradução do artigo de Yerain Diaz [4] , conheci outro olhar bastante interessante e bastante admirador das corrotinas em geral e do assíncio em particular. Apesar desse fato e de outros semelhantes, ainda "seguiremos o outro caminho" :) Concordo apenas em uma coisa com Rob Pike, que "Concurrency Is Not Parallelesm". Competitividade, pode-se até dizer mais difícil, nada tem a ver com paralelismo. E é notável que o Google Translate traduz esta frase como "Paralelismo não é paralelismo." O homem chamado Google certamente está errado. Mas alguém o convenceu disso? :)
Literatura
- Shultais Education. 1. . [ ], : www.youtube.com/watch?v=BmOjeVM0w1U&list=PLJcqk6mrJtxCo_KqHV2rM2_a3Z8qoE5Gk, . . . ( 01.08.2020).
- Computer Science Center. 9. async / await ( Python). [ ], : www.youtube.com/watch?v=x6JZmBK2I8Y, . . . ( 13.07.2020).
- Easy Python. Asyncio python 3.7. [ ], : www.youtube.com/watch?v=PaY-hiuE5iE, . . . ( 01.08.2020).
- Yeray Diaz. Asyncio para o desenvolvedor praticante de python. [Recurso eletrônico], Modo de acesso: www.youtube.com/watch?v=PaY-hiuE5iE , gratuito. Língua. russo (data do tratamento 01/08/2020).