Dieser Artikel ist der Artikel zum 22. Tag von "DSL Adventskalender 2019".
Weihnachten, Silvester, Neujahr und die großen Ereignisse kommen bald. Es scheint die Jahreszeit zu sein, in der es verärgert und weniger beschäftigt wird. Wie ist es bei euch? Am Ende des Adventskalenders ist die Tatsache, dass es von einer kleinen Anzahl von Menschen gedreht wird, kurz vor dem mentalen Zusammenbruch. Der Solist, der bis heute weiter schreibt, steht kurz vor dem Abschluss des Menschen.
Die Mitglieder dieser Ad-Care sind mit DSL verwandt, aber ich werde am OB-Frame teilnehmen! Ich habe eine Grundschule abgeschlossen und bin Ingenieur bei einem bestimmten IT-Unternehmen. Ich möchte zusammenfassen und vorstellen, was ich seit meinem Eintritt in das Unternehmen etwa ein halbes Jahr lang studiert habe.
Um maschinelles Lernen im Web durchführen zu können, müssen Sie die folgenden Punkte beachten.
Um diesen Punkt zu behandeln, handelt es sich um mehrere Prozesse, und es ist möglich, die Start- und Endverarbeitung jedes Prozesses zu verwalten. Programmieren Sie das System. ~~ Es ist nervig. ~~
Erstens ist das nicht blockierende IO-Denkmal asynchron / warten. Wenn Sie das Frontend berührt haben, können Sie es selbstverständlich verwenden. Eigentlich ist es auch in Python.
Im Gegensatz zu async / await von Javascript haben Funktionen mit async jedoch immer ein Collout-Objekt. Es wird zurückgegeben, sodass es nur innerhalb einer Ereignisschleife ausgeführt werden kann.
Es gibt ein Konzept namens System of Systems als konkrete Methode zum Entwerfen eines Systems. Ursprünglich nicht im Software-Design, sondern in anderen Bereichen wie Geschäftsprozessen Ist es wie etwas verwendet? Aber dieses Mal werde ich dies in den Prozessmanagement-Teil aufnehmen.
Ein System besteht aus 0 oder mehr Systemen. Zu diesem Zeitpunkt wird das untergeordnete System in Bezug auf das übergeordnete System als Subsystem bezeichnet. Wenn alle Subsysteme gestartet wurden, wird das übergeordnete System als "gestartet" behandelt. Wenn alle Subsysteme beendet sind, wird das übergeordnete System als "geschlossen" behandelt.
Das System nimmt die in der folgenden Tabelle gezeigten Zustände an. Die Zustände, die von jedem Zustand übergegangen werden können, sind festgelegt, und es ist nicht möglich, plötzlich vom anfänglichen zum laufenden Zustand usw. überzugehen.
Status | Erläuterung | Übergang ist möglich |
---|---|---|
initial | Der Status, der unmittelbar nach der Erstellung des Systems als Anfangswert angegeben wird | ready, disabled |
ready | Ein Status, der angibt, dass das System betriebsbereit ist | running |
running | Geben Sie an, wann das System ausgeführt wird | completed, intermitted, terminated |
completed | Ein Status, der angibt, dass das System die Ausführung normal abgeschlossen hat | - |
disabled | Sie können zu Bereit wechseln, indem Sie den Status entfernen, der angibt, dass das System nicht ausgeführt werden kann, und die Ursache für die Nichtausführbarkeit angeben. | ready |
intermitted | Ein Status, der anzeigt, dass das System ausgefallen ist. Sie können zwischen gestört und ausgeführt beliebig oft wechseln, während das System ausgeführt wird.(Es ist schwierig, es tatsächlich so zu machen) | running |
terminated | Im Gegensatz zu dem Zustand, in dem das System zwangsweise beendet und deaktiviert wurde, ist ein Übergang von hier aus nicht möglich | - |
Die folgende Abbildung ist ein einfaches Zustandsübergangsdiagramm. Wenn der Vorgang auf dem Weg normal und fehlerfrei verläuft, wird der blaue Weg eingeschlagen. Wenn der Prozess aufgrund einer unerwarteten Situation nicht fortgesetzt werden kann, wird er über die rote Route deaktiviert oder beendet. Darüber hinaus wird der Übergang der grünen Route im Wesentlichen durch menschliches Urteilsvermögen und Handeln eingeleitet.
Im vorherigen Abschnitt haben wir jeden Status des Systems vorgestellt und definiert. Als nächstes definieren wir den Zustandsübergang oder den Pfeil in der Abbildung. Die Definition ist etwas hartnäckig, aber es ist eine gute Idee, sie beizubehalten, damit Sie sich beim Schreiben eines Programms keine Sorgen machen müssen. Ich habe wie zuvor einen Tisch und eine Figur vorbereitet.
Überleitung | Erläuterung |
---|---|
activate(Aktivierung) | Führen Sie die Vorbereitungsfunktion aus, die die für die Ausführung erforderlichen Materialien sammelt |
disable(Invalidierung) | Ändern Sie den Wert der Variablen, in der der Status gespeichert ist, in deaktiviert |
enable(Aktivierung) | Ändern Sie den Wert der Variablen, in der der Status gespeichert ist, in "Bereit" |
start(Start) | Führen Sie die Hauptfunktion aus, die eine umfangreiche Verarbeitung ausführt, z. B. maschinelles Lernen und Endlosschleife |
complete(Erledigt) | Führen Sie die Abschaltfunktion aus, um Speicher usw. freizugeben. |
suspend(Suspension) | 実行中のmain関数にSuspensionシグナルを送ります |
resume(Fortsetzen) | 中断中のmain関数にFortsetzenシグナルを送ります |
terminate(erzwungene Kündigung) | Führen Sie die Teardown-Funktion aus, um Speicher usw. freizugeben. |
Neue Wörter wie Vorbereitungsfunktion und Hauptfunktion kamen heraus, Mit diesen wird es einfacher, Programme zu schreiben.
Als konkretes Bild, wenn Sie jedes System erstellen, indem Sie die ursprüngliche Systemklasse erben, Sie müssen super () einfügen, wenn Sie aktivieren oder starten überschreiben. (Da Statusänderungen und Protokollierung bei jedem Übergang durchgeführt werden) Dies ist ärgerlich, sodass Sie es lösen können, indem Sie jeden systemspezifischen Prozess einer anderen Funktion wie Prepare oder Main überlassen.
Obwohl der Titel der Einfachheit halber maschinelles Lernen erwähnt, werden wir diesmal die Schlaffunktion als zeitaufwändigen Prozess ersetzen. Erstellen Sie zunächst die ursprüngliche Systemklasse.
class System():
def __init__(self, name):
self.name = name
self.state = "initial"
self.kwargs = {}
self.log(self.state)
def log(self, msg):
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
line = f"{date}\t[{self.name}]\tpid:{os.getpid():05d}\t{msg}"
print(line)
def prepare(self, **kwargs):
pass
def main(self):
pass
def activate(self):
self.prepare(**self.kwargs)
self.state = "ready"
self.log(self.state)
def start(self):
self.state = "running"
self.log(self.state)
self.main()
def complete(self):
self.state = "completed"
self.log(self.state)
def transit(self):
self.activate()
self.start()
self.complete()
async def run(self, **kwargs):
self.kwargs = kwargs
executor = ProcessPoolExecutor(max_workers=None)
loop = asyncio.get_event_loop()
await loop.run_in_executor(executor, self.transit)
Der Schlaf wird nur parallel ausgeführt, sodass nicht alle endlos eingeführten Zustände und Übergänge implementiert werden: sob :: pray:
Der Konstruktor \ _ \ _ init \ _ \ _ benennt dieses System und legt den Anfangszustand fest. Während des Transports wird der Übergang der blauen Route der Reihe nach ausgeführt. Bei der Implementierung deaktivieren oder beenden Ich denke, dass Sie schön schreiben können, wenn Sie versuchen - außer in diesem Teil.
Im letzten als asynchrone Funktion definierten Lauf ermöglicht run_in_executor, dass der Transit als Collout-Funktion behandelt wird. Bei der Vorbereitung usw. kann je nach Benutzer ein Argument als Argument variabler Länge verwendet werden Ich würde es gerne an Transit übergeben und sogar aktiv, aber im Fall dieses run_inexecutors Multi-Prozess Ich erhalte eine Fehlermeldung, wenn ich versuche, ein Argument variabler Länge zu übergeben. Da es keine Möglichkeit gibt, wird es in der Instanzvariablen kwargs gespeichert.
Erstellen Sie als Nächstes ein System, das das "System, das die Schlaffunktion ausführt" ausführt. Es ist ein verwirrender Satz, aber wenn Sie mehrere Systeme ausführen möchten, Ich möchte vermeiden, direkt in \ _ \ _ main \ _ \ _ zu schreiben, daher werde ich ein appSystem als Wrap-System erstellen.
class appSystem(System):
def prepare(self):
pass
def main(self):
sleep1 = sleepSystem("sleepSystem1")
sleep2 = sleepSystem("sleepSystem2")
systems = asyncio.gather(
sleep1.run(sleep=5),
sleep2.run(sleep=3)
)
loop = asyncio.get_event_loop()
loop.run_until_complete(systems)
Hier kommt die Bedeutung der Trennung von Prozessen wie Activet und Prepare sowie Start und Main zum Ausdruck. Diesmal ist es nur Schlaf, also gibt es nichts Besonderes zu schreiben, um sich vorzubereiten. ~~ Sie können die in der Instanz gespeicherten Variablen zwangsweise schreiben ... ~~
Führen Sie sleepSystem1 aus, das 5 Sekunden lang schläft, und sleepSystem2, das hauptsächlich 3 Sekunden lang schläft. sleepSystem ist ein einfaches System wie dieses:
class sleepSystem(System):
def prepare(self, sleep=3):
self.sleep = sleep
def main(self):
time.sleep(self.sleep)
Fügen Sie danach appSystem.run () mit der Hauptfunktion zur Ereignisschleife hinzu. 13
def main():
app = appSystem("appSystem")
loop = asyncio.get_event_loop()
loop.run_until_complete(app.run())
if __name__ == "__main__":
main()
Lass es uns laufen.
2019-12-14 16:43:28.843830 [appSystem] pid:30360 initial
2019-12-14 16:43:29.196505 [appSystem] pid:21020 ready
2019-12-14 16:43:29.196505 [appSystem] pid:21020 running
2019-12-14 16:43:29.197501 [sleepSystem1] pid:21020 initial
2019-12-14 16:43:29.197501 [sleepSystem2] pid:21020 initial
2019-12-14 16:43:29.799470 [sleepSystem1] pid:29720 ready
2019-12-14 16:43:29.803496 [sleepSystem1] pid:29720 running
2019-12-14 16:43:29.872484 [sleepSystem2] pid:18868 ready
2019-12-14 16:43:29.872484 [sleepSystem2] pid:18868 running
2019-12-14 16:43:32.873678 [sleepSystem2] pid:18868 completed
2019-12-14 16:43:34.804446 [sleepSystem1] pid:29720 completed
2019-12-14 16:43:34.804446 [appSystem] pid:21020 completed
Von links nach rechts Datum, Systemname, PID und Status. Die Zeiten, in denen sleepSystem1 und sleepSystem2 in den Betriebszustand eingetreten sind, sind fast zur gleichen Zeit. Darüber hinaus handelt es sich um separate Prozesse, die gleichzeitig ablaufen und nach 3 bis 5 Sekunden den abgeschlossenen Zustandsübergang ausführen. Und Sie können das fertige appSystem sehen.
Zum Schluss werde ich das gesamte Programm veröffentlichen.
import asyncio
import time
from datetime import datetime
import os
from concurrent.futures import ProcessPoolExecutor
class System():
def __init__(self, name):
self.name = name
self.state = "initial"
self.kwargs = {}
self.log(self.state)
def log(self, msg):
date = datetime.now().strftime("%Y-%m-%d %H:%M:%S.%f")
line = f"{date}\t[{self.name}]\tpid:{os.getpid():05d}\t{msg}"
print(line)
def prepare(self, **kwargs):
pass
def main(self):
pass
def activate(self):
self.prepare(**self.kwargs)
self.state = "ready"
self.log(self.state)
def start(self):
self.state = "running"
self.log(self.state)
self.main()
def complete(self):
self.state = "completed"
self.log(self.state)
def transit(self):
self.activate()
self.start()
self.complete()
async def run(self, **kwargs):
self.kwargs = kwargs
executor = ProcessPoolExecutor(max_workers=None)
loop = asyncio.get_event_loop()
await loop.run_in_executor(executor, self.transit)
class appSystem(System):
def prepare(self):
pass
def main(self):
sleep1 = sleepSystem("sleepSystem1")
sleep2 = sleepSystem("sleepSystem2")
systems = asyncio.gather(
sleep1.run(sleep=5),
sleep2.run(sleep=3)
)
loop = asyncio.get_event_loop()
loop.run_until_complete(systems)
class sleepSystem(System):
def prepare(self, sleep=3):
self.sleep = sleep
def main(self):
time.sleep(self.sleep)
def main():
app = appSystem("appSystem")
loop = asyncio.get_event_loop()
loop.run_until_complete(app.run())
if __name__ == "__main__":
main()
Obwohl es eine Eile war, stellte ich ein Beispiel für das Design von Webanwendungen für maschinelles Lernen vor. Das Beispielprogramm ist nur Sleep, implementiert jedoch keinen WWW-Server oder maschinelles Lernen. Da die Idee selbst dieselbe ist, denke ich, dass es wenig Zeit und Mühe gibt. (~~ Wenn Sie zu viel schreiben, ist es eine unternehmensähnliche Sache, daher ist es erheblich vereinfacht ~~)
Darüber hinaus erfolgt die Kommunikation zwischen Systemen über das grundlegende WebSocket. Es ist eine gute Idee, ein vom wwwSystem getrenntes Websocket-System zu erstellen und es zu einem Subsystem des appSystems zu machen.
Also wie war es? Ich habe es schon lange nicht mehr benutzt, aber ich persönlich mag es wegen seines schönen Designs.
http://itdoc.hitachi.co.jp/manuals/3020/30203M8120/EM810359.HTM
Recommended Posts