2011-07-18 11 views
6

私はサーバー(主にウィンドウ用ですが、マルチプラットフォームを保つことができればすばらしいです)を作成しています。通常のコンソールウィンドウを使用しています。しかし、私はサーバーがtext_to_say_hereやkicknameなどのようなコマンドを実行できるようにしたいと思います。私はどのように非同期入出力を持つことができますか?私はいつも普通のprintf()とgets_sでいくつかのものを試しましたが、それは本当に奇妙なものになりました。C++コンソールウィンドウへの同時入力と出力

私はこの1

感謝のようなものを意味します。

+0

何 "奇妙なもの" を活用するには? – NPE

+0

[恥知らずのプラグ](https://github.com/louisdx/schlagwetter):-) –

+0

は、割り込みハンドラをシミュレートします。あなたは私が推測するのが良いだろう。 –

答えて

0

入力と出力を別々のスレッドに配置できます。なぜあなたはこれをしたいのか分かりませんが、スレッディングは仕事をするべきです。 :)

http://en.wikibooks.org/wiki/C++_Programming/Threading

+1

ああ、いいえ! IOのためのスレッドではなく、非同期でなければなりません! – piotr

+0

よくasynchnourous処理は今ではありませんか? –

+0

はい、非同期操作はスレッドで行われることがよくありますが、標準ライブラリの入出力操作がマルチスレッドセーフではないという問題があります。コンソールに読み書きしようとする複数のスレッドは、書き込みの予測不能なインターリーブが含まれます。したがって、I/O操作にアクセスする前に、ある種のロックを実装する必要があります。 – Jason

3

あなたはスレッドを使用して非同期I/Oをシミュレートすることができますが、もっと重要なのは、次の2回の読み取りの間にミューテックスを共有しなければなりません/スレッドが別のを踏んですべての問題を避けるために、スレッドを書きますスレッドを作成し、別のスレッドの出力の上にコンソールに書き込みます。つまり、std::cout,std::cin,fprintf()などはマルチスレッドセーフではないため、別の読み取りまたは書き込みが既に発生している間に読み取りまたは書き込みが行われる2つの操作の間に予測できないインターリーブパターンが得られます。書き込みの途中で読み込みを試みると簡単に終わることがあります。さらに、コンソールに入力を入力している間に、別の書き込みスレッドがコンソールに書き始める可能性があります。入力として入力しようとしています。

非同期の読み書きスレッドを適切に管理するには、読み込み用と書き込み用の2つのクラスを設定することをお勧めします。各クラスでは、読み込みスレッドの場合はメインスレッドが取り出すメッセージ(書き込みの可能性が高い場合はstd::string)を格納し、書き込みスレッドの場合はメインスレッドがメッセージをプッシュするメッセージキューを設定します。 stdinまたはstd::cinから読み取る前にプロンプ​​トを表示するメインスレッドによってメッセージキューにプッシュメッセージがプッシュされ、プロンプトを出力できる特別なバージョンの読み取りスレッドを作成することもできます。次に、両方のクラスが共通のミューテックスまたはセマフォを共有して、I/Oの予測不能なインターリーブを防止します。いずれかのiostreamコールの前に共通のミューテックスをロックすることにより(その後にロックを解除する)、I/Oの予測不能なインターリーブが回避されます。各スレッドは、クラスの内部メッセージキューへのアクセスより排他性を維持するために使用できる各スレッドに固有の別のミューテックスを追加します。最後に、各クラスのメッセージキューをstd::queue<std::string>として実装することができます。

可能な限りクロスプラットフォームとしてプログラムを作成したい場合は、Boost :: threadsまたは新しいC++ 0x std :: threadsライブラリを使用して実装することをお勧めします。

1

コンソールウィンドウを切り取ってコマンドと制御にTCP接続を使用すると、サーバーはマルチプラットフォームを維持するのがずっと簡単になり、さらに簡単で柔軟になります。

4

クイックコードは、C++ 11個の機能(すなわち、クロスプラットフォーム)

#include <atomic> 
#include <thread> 
#include <iostream> 

void ReadCin(std::atomic<bool>& run) 
{ 
    std::string buffer; 

    while (run.load()) 
    { 
     std::cin >> buffer; 
     if (buffer == "Quit") 
     { 
      run.store(false); 
     } 
    } 
} 

int main() 
{ 
    std::atomic<bool> run(true); 
    std::thread cinThread(ReadCin, std::ref(run)); 

    while (run.load()) 
    { 
     // main loop 
    } 

    run.store(false); 
    cinThread.join(); 

    return 0; 
} 
関連する問題