コルティンのない䞖界。プログラマヌのためのクラッチ-asyncio

1.はじめに



飛ぶこずを孊んだ人はもう這うこずはありたせん。しかし、原則ずしお「飛べない」人に察しおも傲慢であっおはなりたせん。どちらもごく普通のこずです。どちらも尊敬され、尊敬されおいたす。人にずっお、これは職業を遞ぶようなものです。あなたは、埓来、パむロットかドラむバヌのどちらかです。同じ動物の堎合、それは同じです-あなたはワシかオオカミのどちらかです、すなわち飛ぶか逃げる逃げるしかし、圌の抂念、カテゎリヌ、態床、思考の䞭で男性だけがキャラクタヌに特城を䞎え、圌らに察しお圌自身の態床を発達させたした。確かに、ニュアンスがありたす。だから、おそらく、それはパむロットの職業よりも立掟でロマンチックですが、これをトラック運転手や航空機の蚭蚈者に説埗しおみおくださいそしお、ここで議論するのは難しいです今でも倚くの宇宙飛行士がいたすが、2番目の女王はただいたせん



私たちはプログラマヌです。皋床はさたざたかもしれたせんが、確かにいく぀かありたす。぀たり、私たちは異なっおおり、さたざたな方法で考えるこずもできたす。プログラマヌが䞀貫しおしか考えおいないずいう声明は、人が走るだけであるずいう事実ず同じように、䞀方的で、有害で、冒涜的でさえありたす。圌は時々-そしお飛ぶ。パむロットのように定期的に行う人もいれば、宇宙飛行士のように数か月間も継続的に行う人もいたす。䞀貫した思考のアむデアは、人間の胜力を䜎䞋させたす。ある時点で、しばらくの間、あなたはそれを信じるこずさえできたすが、「それでも、それは倉わりたす」-これは遅かれ早かれ人生が犠牲になるずいう事実に぀いおです。



PythonのAsyncioは、比喩的に蚀えば、誀った䞊列思考の飛行を暡倣する゜フトりェアクラッチです。手を振っおバりンドするようなものです。それは時々、面癜くお䞍噚甚に芋えたす。特定の状況では、これも解決策です。氎たたりを越えお汚れるこずができたすが、匷床が蚱せば、飛び越える方がよいでしょう。しかし、おそらくプログラマヌは力を欠いおいたすか



課せられた「゜フトりェアクラッチ」を砎棄しお、゜フトりェアルヌチンの䞊に急䞊昇しおみたしょう。そしお、それをゞャンプではなく、あるいはそれほど高くも長くもしないようにしたすが、それでも、特にクラッチず比范しお、フラむトです。結局のずころ、か぀おモザむスキヌアレクサンダヌフェドロビッチモスクワ地域のモザむスキヌ垂裁刀所ず混同しないでください;たたは同じラむト兄匟が初めお空䞭で数癟メヌトルを克服したした。はい、そしお珟代の航空機のテストは、滑走路ず滑走路からの短期間の分離から始たりたす。



2.asyncioを䜿甚した非垞に単玔な䟋



Pythonでの飛行から始めたしょう。フラむトプログラムは簡単です。ヒュヌズラグに「Blog」、「News」、「Forum」ずいう名前の飛行機がありたすただし、スパむダヌの画像の元のバヌゞョンでは、[1]を参照しおください。圌らは同時に離陞したす。誰もが特定の時間内にパスのセグメントを飛行し、たずえば、セグメントの番号がカバヌされたフラグを投げる必芁がありたす。これは3回実行する必芁がありたす。そしお、着陞するだけです。



Pythonでは、この動䜜のモデルが蚘述され、リスト1のコヌドによっおシミュレヌトされたす。



リスト1.スパむダヌプレヌンのPythonコヌド
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))




このような「フラむト」のシミュレヌション結果は次のずおりです。



ブログ1

ニュヌス1

フォヌラム1

ブログ2

ニュヌス2

フォヌラム2

ブログ3

ニュヌス3

フォヌラム

33.00



なぜこれがビデオ[1]で詳现に説明されおいるのか。しかし、想像力ず同時で、私たちみんなシナリオに埓っお-非同期の飛行私たち3「プレヌン」になるasyncioを䜿甚せずに-自動モデルに基づいお異なる方法で提瀺したす。たずえば、リスト2は、オヌトマトン遅延のコヌドを瀺しおいたす。これは、リスト1のawait asyncio.sleep1ずいう行で衚される、asyncioモゞュヌルからの非同期遅延の類䌌物です。



リスト2.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




遅延倀ず遅延オブゞェクトを䜜成したオブゞェクトぞのポむンタは、クラスコンストラクタを介しお枡されたす。ポむンタは、遅延を削陀した埌、䜜成時に停止された芪プロセスを続行するプロセス制埡機胜に必芁です。



リスト3は、非同期スパむダヌプレヌンに察応するオヌトマトンを瀺しおいたすリスト1も参照。最も悪倢のような堎合でも、Pythonプログラミング゚ヌスがこれを倢芋ない可胜性が非垞に高いです。4行の゜ヌスコヌドは15倍になりたしたこれは、䞀般的な兞型的なPythonコヌド、特にasycioを賞賛する理由ではありたせんか、少なくずも、オヌトマトンプログラミングに察する「通垞のテクノロゞヌ」の利点の蚌拠ではありたせんか



リスト3.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




自動フラむトの結果は次のずおりです。



ニュヌス1

フォヌラム1

ブログ1

ブログ2

ニュヌス2

フォヌラム2

ニュヌス3

フォヌラム3

ブログ

33.00



しかし、話し合いたしょう。コヌドサむズの増加は、Pythonのポむンタの問題が原因でした。その結果、ペヌゞごずにクラスを䜜成する必芁があり、コヌドが3倍になりたした。したがっお、玄15ではなく、玄5倍の音量で話す方が正しいです。プログラミングにおけるより熟緎した「Pythonパむロット」は、この欠点を取り陀くこずさえできるかもしれたせん。



しかし、䞻な理由はただポむンタヌではありたせん。以䞋に瀺すC ++コヌドは、ポむンタヌを完党に自由に操䜜できるため、クラスごずにさらに倚くの行がありたす。その理由は、䜿甚されおいる蚈算モデル、その蚘述の蚀語、およびそれに基づくアルゎリズムの実装ぞのアプロヌチです。図図は、ブロック図圢匏の埓来のスパむダヌ平面モデルおよびオヌトマトンモデルを瀺しおいる。同等の倉換が可胜ですが、倖芋䞊および品質䞊、これらは異なるモデルであるこずがわかりたす。 Automataには状態がありたすが、ブロック図にはそれらの痕跡すらありたせん。 Automataは、定矩䞊、離散時間で動䜜し、ブロック図はこれを倢芋さえしたせん。これはすべお、モデルの実装に特定の矩務を課したす。



離散時間の抂念がないこずは、既存のブロック図プログラミングモデルの問題の本質であり、厳密に蚀えば、それに察しお実珟䞍可胜なこずを実珟する必芁がありたす。䞊列プロセス。オヌトマトンの堎合、䞊列プロセスおよび非同期のモデルずしおのオヌトマトンネットワヌクが自然な状態であるこずを思い出しおください。



図1.スパむダヌプレヌンの自動モデルずブロック図モデル
image



ただし、別のプロセスのレベルでも、モデルには、モデルの蚀語ず実装に投圱される違いがありたす。これらの品質のおかげで、䞀貫性のあるブロック図の謝眪者は、明瀺的たたは暗黙的に、それを非垞にコンパクトに蚘述するこずを可胜にする蚀語構造を䜜成したした。同じforルヌプ、たたは少なくずも暗黙的に暗黙的に実行される挔算子のシヌケンスアクションy1、y2、y3を䜿甚したす。



フロヌチャヌトの堎合、問題なく1぀のボックスにアクションをリストできたす。これにより、アクションの順次的な性質が倉わるこずはありたせん。オヌトマトンが状態s2、s3の遷移を状態s1のサむクルに眮き換え、アヌクを同じアクションでマヌクするず、アルゎリズムの意味が倉わりたす。その䜜業に䞊列凊理を導入したす。䞊蚘のアクションは厳密に順番に実行する必芁があるため、これによりオヌトマトンモデルの倖芳が事前に決定されたす図1を参照。有限オヌトマトンは、「二重思考」を蚱可しないモデルです。



ブロック図に離散時間がないこずが圌らの利点でした。しかし今、これは圌らの䞻な欠点になっおいたす。それは冒涜的ではないように芋えるかもしれないので、それは圱響を及がしたす、そしお考え方。シヌケンシャル蚀語は、プログラマヌに他の䜕かを吊定するこずによっお、プログラマヌのシヌケンシャルな考え方を正圓化したす-䞊列。これは、既存の非同期プログラミングの構築を正圓化し、同じasyncioパッケヌゞのオペレヌタヌのセットず機胜を提瀺するものです。そしお、シヌケンシャルプログラムに粟通しおいるプログラマヌが非同期ほが䞊列に倉換できるのは、たさにこのアプロヌチであるず䞻匵されおいたす。



しかし、蚘事ずその画像のトピックに戻りたす。私たちは「飛行機」が欲しかったのですが、それを手に入れたしたフラむト、より正確には、目に芋える結果は、倖芳は倚少異なりたすが、本質的に完党に区別できたせん。それらは、フラグが遞択され、プロトコルに異なる順序で蚘録されるように解釈できたすが、「飛行機」自䜓は本​​来のように飛行したした。同時にそしお同時に圌らの旗を捚おた。そしお、それらがどのような順序で蚘録されたか-圌らが蚀うように、ケヌスは10番目です。䞻なものは実珟され、実行されたすそれらのリリヌスの順序ず時間はフラむトプログラムに察応したす



コヌドを短くするこずができたす。したがっお、明らかに、1぀のクラスのコヌドのみに制限するこずができたす。むベントルヌプコヌドを非衚瀺にするこずもできたす。同時に、゜ヌスコヌドで、非同期の背埌に隠されおいる゚ンゞンコンパヌトメントコヌドを開いおオペレヌタヌを埅぀堎合、オヌトマトンコヌドのボリュヌムはそれほど怖くないでしょう。



3.Pythonでオヌトマトンを実装する際の問題に぀いお



自動コヌドの出珟を匕き起こした問題に぀いおさらに詳しく芋おいきたしょう。そこに隠す最埌のものは、゜ヌスコヌドず比范しおこれたでのずころ巚倧に芋えたす。しかし、Mozhaiskyの最初の航空機は、珟代の「也燥」ずはほど遠いものであり、最初の車は、珟代のどの航空機ずもそれほど倉わらなかったこずに泚意しおください。提瀺されたオヌトマトンコヌドの問題は、Python蚀語の珟圚の理解に倧きく関係しおおり、おそらく、蚀語自䜓の機胜にはそれほど関係がないこずを匷調しおおきたす。



それにもかかわらず、最初の問題は、オヌトマトンモデルの蚘述蚀語に関連しおいたす。 C ++では、蚀語によっお解決されたす。 Pythonではそのような可胜性は芋圓たりたせん。残念ながら、圌らが今時々蚀うように、たったく蚀葉から。そのため、if-elif-else蚀語の制埡挔算子に基づいおオヌトマトンを実装する方法を基本ずしたした。さらに、CPSUaでは、オヌトマトン自䜓に加えお、䞊列凊理を完党に実装するためにシャドりメモリずオヌトマトンスペヌスが導入されたこずを思い出したす。これがないず、オヌトマトンプログラミングの可胜性は非垞に限られおおり、倚くの点で劣っおいたす。



すでに述べた次の問題はポむンタヌです。 C ++では問題ありたせん。 CPSUaのフレヌムワヌク内で、OOPパラダむムに埓っお、基本的なオヌトマトンクラスが䜜成され、そこから適甚されたオヌトマトンクラスが生成され、それらのパラメヌタヌはポむンタヌだけでなくアドレスにもなりたす。これらすべおにより、倚くの䞊列盞互䜜甚プロセスを含むタスクを簡単、コンパクト、非垞に効率的に蚘述および実装できたす。



以䞋は、怜蚎した䟋に盞圓するC ++オヌトマトンクラスのコヌドです。リスト4の遅延コヌドは、リスト1のawait asyncio.sleep1の行ず同等です。グラフ圢匏では、図1のFAwaitSleepオヌトマトンモデルに察応したす。1.そのような、そしおそのようなオヌトマトンだけが非同期ず芋なすこずができ、蚈算フロヌを遅くするこずはありたせん。同じ図のFSleepは、通垞のsleep挔算子に察応したす。より簡単ですが、y1の䜜甚により通垞の順次遅延が発生するため、離散時間モデルが砎壊されるこずが保蚌されおいたす。そしお、これはもはや䜕の圹にも立たない。



リスト4.非同期遅延コヌド
//  (  )
#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; }




スパむダヌプレヌンのC ++コヌドをリスト5に瀺したす。このコヌドは、Pythonコヌドのブロック図よりも、そのモデルにはるかに適しおいたす。特に、オヌトマトンの遷移テヌブルずオヌトマトングラフの倖芳を比范するず。それらは、同じ抜象的な抂念、぀たりオヌトマトンを蚘述するための単玔に異なる圢匏です。たた、遅延を䜜成するずきに芪クラスぞのポむンタがどのように枡されるかを瀺したすアクティビティy1のFCallメ゜ッドの呌び出しを参照。



リスト5.サむトペヌゞの読み取りをシミュレヌトするスパむダヌプレヌンのコヌド
// "".   
#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; }




いわゆるむベントルヌプの機胜を実装するコヌドはありたせん。単にそれの必芁はありたせん。その機胜は、CPSUa環境のコアによっお実行されたす。オブゞェクトを䜜成し、それらの䞊列実行を個別の時間で管理したす。



4.結論



簡朔さは必ずしも才胜の姉効であるずは限らず、時にはそれは舌の結び぀きの兆候でもありたす。確かに、䞀床に区別するこずは困難です。倚くの堎合、PythonコヌドはC ++コヌドよりも短くなりたす。しかし、これは単玔なケヌスでは䞀般的です。゜リュヌションが耇雑になるほど、この違いは少なくなりたす。結局、゜リュヌションの耇雑さでさえ、モデルの機胜によっお決定されたす。オヌトマトンモデルは、ブロック図よりもはるかに匷力です。



自動化ず䞊列化は、たず第䞀に、耇雑さの問題を解決し、それず戊うための非垞に効果的な手段であり、プログラムの速床を䞊げる手段ではありたせん。これはすべおオヌトマトンモデルであるため、䞊列凊理をPythonで実装するのは困難です。そのため、チップやバッテリヌなどすべおにもかかわらず、その方向に私を説埗するのは困難です。私はC ++環境にもっず泚意を払い、同じコロチンをそれに導入するこずはあたり正圓化されたせん。このモデルは䞀時的なものであり、その実装の理由は倧郚分が匷制されおいたす。そしお、䞊列モデルを遞択する問題が解決されたら、この「クラッチ」をどうしたすか



したがっお、申し蚳ありたせんが、私の奜みはただC ++偎です。そしお、あなたが私の専門的な興味のある分野、いわゆる「䞍気味な」ハヌドリアルタむムの産業システムを考えるず、私はそのように遞択するこずはできたせん。はい、ある皮の環境、ある皮のサヌビスはPythonを䜿甚しお䜜成できたす。䟿利、高速、プロトタむプがたくさんありたす。等しかし、゜リュヌションの䞭栞である䞊列モデル、プロセス自䜓のロゞックは、明確にC ++であり、明確に自動化されおいたす。もちろん、ここではオヌトマトンがより重芁であり、支配的です。しかし、coroutinesではありたせん:)



さらに...ロケットモデルの実装に泚意を払いながら、ビデオ[2]をご芧ください。圌女に぀いお、12分頃からビデオが語りたす。機械を䜿甚するための講垫ぞの敬意:)そしお甘い埡銳走のために、[3]からの別の解決策..。それは非同期プログラミングず非同期の粟神に基づいおいたす。実際、すべおはこの䟋、぀たりPythonでのネストされたオヌトマトンの実装から始たりたした。ここでは、入れ子の深さは䞊蚘の䟋よりもさらに倧きくなっおいたす。リスト6は、゜ヌスコヌドずそれに察応するオヌトマトンPythonを瀺しおいたす。図では 2は自動茶飲甚モデルであり、リスト7はVKPaの同等のC ++実装を瀺しおいたす。比范、分析、結論の匕き出し、批刀...



リスト6.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




図2.お茶を飲む自動モデル
image



リスト7.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



すでに蚘事を曞いた埌、Yerain Diaz [4]による蚘事の翻蚳を読んだ埌、私は別のかなり興味深く、むしろ称賛に倀する、䞀般的なコロチン、特に非同期の芋方に粟通したした。この事実や他の人がそれを奜むにもかかわらず、私たちはただ「反察の方向に進む」でしょう:)私はRob Pikeず、「䞊行性は䞊列性ではない」ずいう1぀のこずに同意したす。競争力は、より厳しいずさえ蚀えるかもしれたせんが、䞊列凊理ずはたったく関係がありたせん。そしお、GoogleTranslateがこのフレヌズを「䞊列凊理は䞊列凊理ではない」ず翻蚳しおいるこずは泚目に倀したす。グヌグルずいう男は確かに間違っおいたす。しかし、誰かが圌にこれを玍埗させたしたか:)



文献



  1. Shultais Education. 1. . [ ], : www.youtube.com/watch?v=BmOjeVM0w1U&list=PLJcqk6mrJtxCo_KqHV2rM2_a3Z8qoE5Gk, . . . ( 01.08.2020).
  2. Computer Science Center. 9. async / await ( Python). [ ], : www.youtube.com/watch?v=x6JZmBK2I8Y, . . . ( 13.07.2020).
  3. Easy Python. Asyncio python 3.7. [ ], : www.youtube.com/watch?v=PaY-hiuE5iE, . . . ( 01.08.2020).
  4. むェレむディアス。緎習䞭のpython開発者のためのAsyncio。[電子リ゜ヌス]、アクセスモヌドwww.youtube.com/watchv = PaY-hiuE5iE、無料。蚀語。ロシア 治療日2020幎8月1日。



All Articles