イベントはGUIプログラミングにのみ使用されますか?
通常のバックエンドプログラミングでは、この別のことが起こったときにどのように処理しますか?
いいえ。これらは、オブザーバーを実装し、クラスが変更に対して閉じられていることを確認するために本当に便利です。
新しいユーザーを登録するメソッドがあるとします。
public void Register(user) {
db.Save(user);
}
次に、誰かがメールを送信することを決定します。これを行うことができます:
public void Register(user) {
db.Save(user);
emailClient.Send(new RegistrationEmail(user));
}
しかし、変更がクローズされることになっているクラスを変更しただけです。おそらく、この単純な疑似コードでは問題ありませんが、本番用コードで狂気になる方法である可能性があります。このメソッドが、新しいユーザーを作成するという本来の目的とほとんど関係のない30行のコードになるまでどれくらいかかりますか?
クラスにコア機能を実行させ、ユーザーが登録されたことを聞いている人に通知するイベントを発生させ、必要なアクション(電子メールの送信など)を実行できるようにする方がはるかに便利です。
public void Register(user) {
db.Save(user);
RaiseUserRegisteredEvent(user);
}
これにより、コードをクリーンで柔軟に保つことができます。 OOPの見落とされがちな部分の1つは、クラスが互いにmessagesを送信することです。イベントはこれらのメッセージです。
いいえ。
非GUIロジックで使用されているイベントの典型的な例は、データベーストリガーです。
トリガーは、特定のイベント(INSERT、DELETEなど)が発生したときに実行されるコードです。私にはイベントのようです。
これは、ウィキペディアのイベントの定義です。
コンピューティングでは、イベントはソフトウェアによって認識されるアクションまたは発生であり、ソフトウェアによって処理されます。コンピュータイベントは、システムによって、ユーザーによって、または他の方法で生成またはトリガーできます。通常、イベントはプログラムフローと同期して処理されます。つまり、ソフトウェアには、イベントが処理される1つ以上の専用の場所があり、多くの場合はイベントループになります。イベントのソースには、ユーザーが含まれます。ユーザーは、たとえばキーボードのキーストロークを介してソフトウェアと対話できます。別のソースは、タイマーなどのハードウェアデバイスです。ソフトウェアは、独自のイベントセットをイベントループにトリガーすることもできます。タスクの完了を伝えるため。イベントに応じて動作を変更するソフトウェアは、多くの場合インタラクティブであることを目的として、イベント駆動型であると言われています。
すべてのイベントがユーザーによって生成されるわけではありません。前に述べたように、いくつかはデータベースのINSERTによって、またはcrontabのようなタイマーによって生成されます。
この定義には、一部のプログラムまたはシステムが"イベント駆動型で、多くの場合インタラクティブであることを目的とする"であると記載されています。 、対話性を提供するため(CLIのプログラムもインタラクティブにすることができるため、必ずしもGUIではないがGUIのように).
イベントベースのプログラミングは、実際には高性能のサーバープログラミングにも使用されます。
一般的なサーバーワークロードでは、結果の処理のほとんどの時間は実際にはI/Oから行われます。たとえば、(7200 RPM)のハードディスクドライブからデータをプルすると、最大8.3ミリ秒かかることがあります。最新のGHzプロセッサの場合、これは約100万クロックサイクルに相当します。 CPUが毎回データを待つ(何もしない)場合、LOTのクロックサイクルが失われます。
従来のプログラミング手法では、複数の threads を導入することでこれを回避しています。 CPUは数百のスレッドを同時に実行しようとします。ただし、このモデルで問題となるのは、CPUがスレッドを切り替えるたびに、 コンテキストスイッチ に数百のクロックサイクルが必要になることです。コンテキストスイッチとは、CPUがスレッドローカルメモリを CPUのレジスタ にコピーし、古いスレッドのレジスタ/状態をRAMに保存する場合です。
さらに、各スレッドは、その状態を保存するために特定の量のメモリを使用する必要があります。
今日、ループで実行される単一のスレッドを持つサーバー用のプッシュがありました。次に、作業の一部が メッセージポンプ にプッシュされます。これは、単一のスレッドのキューとして機能します(UIスレッドと同様)。 CPUは、作業が完了するのを待つのではなく、ハードディスクドライブアクセスなどのコールバックイベントを設定します。これにより、コンテキストの切り替えが減少します。
そのようなサーバーの最良の例は Node.js です。これは、適度なハードウェアで100万の同時接続を処理できることが示されていますが、Java/ Tomcat サーバーは、数千で闘う。
イベントはまた、ネットワークプログラミング(例:Nginx)で頻繁に使用され、高価なビジー待機ループを回避し、特定の操作を正確に知るためのクリーンなインターフェイスを提供します利用可能です(I/O、緊急データなど)。これは C10k問題 の解決策でもあります。
基本的な考え方は、イベントを監視するための一連のソケット(つまりネットワーク接続)をOSに提供することです。それらすべて、または特に関心のある一部(たとえば、読み取りに使用できるデータ)を監視します。このようなアクティビティがリスト内のいずれかのソケットでオペレーティングシステムによって検出されると、APIによって探していたイベントの通知が届きます。通知は、それがどこから来たかを分類し、それに応じて動作する必要があります。 。
さて、これは低レベルで抽象的なビューであり、さらに適切にスケーリングするためにトリッキーです。ただし、それをクロスプラットフォームの方法で処理する高レベルのフレームワークはたくさんあります。PythonではTwisted、C++ではBoost.Asio、Cではlibeventが思い浮かびます。
組み込みシステムは、明示的にプログラムされていなくても、ほとんどの場合、本質的にイベント駆動型です。
これらのイベントは、ハードウェアの割り込み、ボタンの押下、アナログからデジタルへの読み取り期間、タイマーの期限切れなどから発生します。
低電力組み込みシステムは、イベント駆動型である可能性がさらに高くなります。彼らはほとんどの時間をスリープ状態(低電力モードでCPUスリープ状態)で過ごし、何かが発生する(その「何か」はイベントです)のを待ちます。
イベント駆動型組み込みシステムの最も一般的で人気のあるフレームワークの1つは Quantum Platform(QP) です(QPはLinux、Windows、およびUNIXのようなOSでも動作します)。プログラムは一般的な意味での「順次」ではなく、システム状態と現在のイベントに応じて呼び出される「コールバック」のセットであるため、イベント駆動型プログラミングに適しています。
イベントメッセージ グレゴールホープ。
Event Driven Architectures Gregor Hohpe。
SEDAアーキテクチャ 、ウェールズ、キュラー、ブリューワー。
何かが発生したときに通常のバックエンドプログラミングでこれをどのように処理しますか?
Finite State Machine は1つの一般的なアプローチです
Given(State.A)
When(Event.B)
Then(State.C)
.and(Consequences.D)
非組み込みシステムの場合、私がC#で行っていたのはSCADAシステムでした。システムで生成されたイベントの一部がロード解除され、他の部分がデータベースに新しい状態を書き込んでいたときに、ウェアハウスで発生していたことに関連する多くのイベントがありました。もちろんGUIクライアントもいくつかありましたが、倉庫の状態を反映したデータベースの状態を表示するだけでした。つまり、イベントとスレッドに基づくバックエンドサーバーソフトウェアでした。開発はかなり困難です。
組み込みシステムでは、イベントは割り込み中に発生します。タイマーからI/Oまで、多くの割り込みソースがあります。
また、RTOSはイベントも持つことができます。1つの例は、別のタスクからのメッセージを待っていることです。