日記帳だ! with Tux on Libserver

二度目の大改造!! 日記帳…か?を継承し、より柔軟でパワフルなBlogに変身しました。

RSSに対応しています。リンク・コメント・トラックバックは自由にしていただいてほぼ問題ありません。
RSS購読方法、僕のリンク・コメント・トラックバックについての考えを読むことをおすすめします。

キーが押されるまで待ってみよう

さて、今日はずいぶんプログラムを書いたぞ。
そんな中で以下のことを実現したかった。
ある部分を実行中にqを押せば終了し、押されなければ最後まで実行して終了する。
しかしこれが非常に難しかった。
C++の標準ライブラリのstd::cinから読み込めると思ったがそうはいかない。
実際にはPOSIX関数由来 kbhit()とgetch()を使うことに。
これとboost::threadを組み合わせて作ってみた。
#include <iostream>
#include <boost/thread.hpp>
#include <boost/ref.hpp>
#include <conio.h>
class Stoppable{
private:
boost::thread thread;
public:
Stoppable(void):thread(boost::ref(*this)){}
void operator()(void){
for(int i=0;i<10;i++){
boost::thread::sleep(boost::get_system_time()+boost::posix_time::milliseconds(1000));
std::cout << "==" << i << "==" << std::endl;
}
}
bool Join(void){
while(1){
if(this->thread.timed_join(boost::get_system_time()+boost::posix_time::milliseconds(100))) return true;
if(kbhit()&&getch()=='q'){
this->thread.interrupt();
return false;
}
}
}
};
100msまで終了待機して、それで終了しなければkbhit()でキー入力を確認し、されていたらキーをgetch()で読み取ると。
こういう要領になっています。
これでJoinメソッドを動かせば、終了かqを待機するわけだが、これには問題があることが分かった。
オブジェクトを破棄するとスレッドも停止されると思い込んでたんだが、そうもいかないらしい。
なのでオブジェクトが破棄されてもスレッドは動き続けたままだった。
どうすればいいのかはよくわからなかったんだが、interruptすればスレッドが止まるらしい。
というわけでthis->thread.interrupt();っていうのを書き足しておいた。
これで終了時には止まっている。
多分これで大丈夫。
これで途中中断機能がつけられた。やったー。
まぁやってること自体は簡単なことなんですけどねぇ。
元々boost::condition_variableがいるかと思ったんだがいらんかったわ。
ちなみにこれの使い方はこんな感じ。
boost::condition_variable stop;
//別のスレッド
stop.notify_all();
//待機するメソッド
boost::mutex mutex;
boost::mutex::scoped_lock lock(mutex);
stop.wait(lock);
なんで待機する方にmutexが必要なのかはよくわからないが、まぁこうすればOK。
あとtimed_waitとかもあるのでなかなか楽しそう。
だが結果的には使わなくても済んでしまった。
やっぱりマルチスレッドってのは大切だと思いましたね。
しょうもないことだけどマルチレッドなしではどうにもならないってことはやっぱりあるから。
そういうときBoostがあって本当によかったなと思わせてくれますね。
Author : Hidemaro
Date : 2009/09/03(Thu) 23:37
コンピュータ・インターネット | Comment | trackback (0)

Tools