2009-08-16 4 views
0

各オブジェクトが独立して動作するクラスがあります。たとえば、オフサイトの多くのサーバーでデータベースからさまざまなテーブルを取得している可能性があります。しかし、内部的には、いくつかのテーブルがリンクされていることがわかりました。には、の応答を一切必要としないコマンドをグループ化することで、かなりの量のIOを節約できます。私の目標は、次のような表のためのインターフェイスを使用してコードを書くことができるようにすることです:スレッドを使用しないコマンドキューイング

void bar() { 
    // queue time is 500 milliseconds 
    Table::queue_time = 500; 
    Table a("foo"),b("baz"),c("cat"); 

    // Call some function for members of this class 
    a.add(2); 
    b.add(5); 

    // Command is sent to database 
    sleep(1); 

    // This command will be sent later 
    c.add(5); 
} 

私はこのコードは、実際には、実際にはデータベースに2つのコマンドを送信します。最初にa.add()を呼び出した後、500ms後にデータベースにコマンドを発行するような一種の「キュー」を開始します。 b.add()が呼び出されると、この新しい命令がこのキューに投げられるようにしたいと思います。しかし、スリープが発生して(そして、時間が命令を送るのに十分な時間が経過しているので)、私はc.send()が実際に新しいキューを開始し、500ms以内に再び送信することを望みます。

しかし、私はできるだけスレッドなしでこれをやりたいのです。それは可能なのですか(私はそう思っていないと思います)?もしそうでなければ、C++のどのツールが仕事に適しているのですか?そのスレッドがスリープしている間に読み込まれる前に編集されるオブジェクトとどのように通信できますか?

(実際には、これはデータベースとは何の関係もありませんので、これは彼らのために役に立たないだろうということを心配しないでください)

答えて

0

あなたがスレッドを使用することができない場合は、あなたが定期的にしなければなりません経過時間の量をテストし、必要に応じてキューをフラッシュするルーチンに呼び出します。

スレッドを使用する場合は、ある種のロックを使用して、キューにアクセスするスレッドの相互排他を保証することができます。読み込みと書き込みの両方でロックを取得する必要があり、キュー内の要素は追加後に変更しないでください。

これを行うもう1つの方法は、要素をキューに単純にバッファすることです。キューが大きすぎる場合は、明示的にフラッシュします。

+1

あなたが定期的に介入するルーチンを書く場合、実際にあなた自身でスレッドシステムを書いています。これはライブラリベンダーの方が良いかもしれませんが、既存のものを使用できる場合はそうではありません。 – xtofl

+1

いいえ、「介入」しません。自分で呼びます。ゲームのようなループ集約型アプリケーションでは、多くの意味があります。同様に、Windowsの共通のタイマー機能は、メッセージループを使用して同じ方法で実装されます。 –

3

まず、command patternについてお読みください。あなたのコマンドは、スタック上に順番に入れられるオブジェクト(必要ならばリスト)、FIFO(先入れ先出し)でなければなりません。しかし、スタック内のすべてのコマンドを実行して実行するには、エグゼキュータが必要です。私はあなたがスレッドを使用する準備が必要だと思う...それらを完全に避けることはできません。待っていることに関して:特別なタイプのコマンド。待機するコマンド(現在のスレッドをスリープ状態にする)。エグゼキュータは、すべてのコマンドを1つずつ実行し、待機コマンドを実行するときには...まあ待っています。以上です !

待機コマンドの目的を無効にするため、新しいスレッドですべてのコマンドを開始しないでください。

元に戻す機能は、このパターンに基づいています。コマンドをスタックに入れて実行し、それらを "完了"スタックに入れます。また、元に戻す場合は、実行者が「完了」スタックの各コマンドを「逆方向」に実行します。実装の詳細は取り上げませんが、興味があれば深く掘り下げることができます。

2

を「500msの中に、再び、送信されます新しいキューを開始」キューの「始まり」は完全に理にかなっていないキュー

「を開始するために 『』私はのソートが欲しいです」 。待ち行列は通常受動的なものです。

「サーバー」は、コマンドをキューから取り出して実行します。したがって、通常はコマンドを取得して500ミリ秒待機するサーバーが必要です。右?

時々、500msの待機を無効にしたい場合があります。右?

あなたは「スケジューリング」問題があります。キューイングの問題ではありません。 500ミリ秒のスケジューリング間隔で実行するコマンドがあり、そのスケジューリング間隔を変更したい場合もあります。

スケジュールは静的であることに注意してください。あなたはスケジュールの途中で眠る必要はありません。コマンドを実行し、500ミリ秒待機する、CommandWithAWaitクラスがあります。または1秒待つ。

a = CommandWithAWait(Table("foo").add(2), 500); 
b = CommandWithAWait(Table("bar").add(5), 1000); 
c = CommandWithAWait(Talbe("baz").add(5), 500); 

s= Schedule(); 
s.add(a); 
s.add(b); 
s.add(c); 
s.go(); 

何かがあなたの話しているようです。この場合、Scheduleクラスは与えられたコマンドを実行し、適切な遅延でそれらを実行することができます。実際の「スレッド」ビジネスはありません。

+0

「スケジューリング」という用語をコインにした素晴らしい洞察!実際、スレッドビジネスはスケジュールを実行する手段となり得る。 – xtofl

+0

それは私がやりたいことと全く同じですが、トリックは私が決して "行く"ことは決してできません。私は単に、実行中のタイマーがなくなったとき、または新しいタイマーを500ms作成するときにコマンドを追加した後に行くと仮定したいと思います。 – duckworthd

+0

@duckworthd: 'Schedule'の' go'メソッドはループです。コマンドを実行します。それは必要な時間眠る。 –

関連する問題