私は無限ループでいくつかの作業をするオブジェクトを持っています。 main()
はオブジェクトをインスタンス化し、run()
メソッドを呼び出します。私はスレッドを使いたくないので、私はオブジェクトの実行を止めるための解決策が必要です。あなたの下に、私が思いついたものが見えます。シグナルをキャッチする:シグナルハンドラとしてメンバ関数を使用する
struct Foo
{
void run()
{
running = 1;
while (running)
do_something_useful();
std::cout << "Execution stopped." << std::endl;
}
bool running;
void catch_signal(int signal)
{
std::cout << "Caught signal " << signal << std::endl;
if(signal == SIGTERM)
running = false;
}
};
ご覧のとおり、信号を非同期で送信する必要があります。したがって、私はシグナルハンドラとsigaction
を使用します。 main
の下に私は使用すると想像することができます。私は今、何を期待する
int main(int argc, char** argv)
{
Foo foo;
struct sigaction sigIntHandler;
boost::function< void (int) > f;
f = std::bind1st(
std::mem_fun(&Foo::catch_signal), &foo);
f(5); // this call works
sigIntHandler.sa_handler = f; // compiler complains, "cannot assign ..."
sigemptyset(&sigIntHandler.sa_mask);
sigIntHandler.sa_flags = 0;
sigaction(SIGTERM, &sigIntHandler, NULL);
s.run();
}
:私がキャッチされ、私のオブジェクトは、反復処理を停止し、メインに戻ることになりますSIGTERM
を送信するまでプログラムが実行されます。
私は今、2つの質問があります
(A)あなたは「コンパイラが文句を言う」とマークされた行を参照してくださいコードでは、メッセージが私が作るように変更しなければならないのは何
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
のようなこの作品?私はf
がvoid f(int)
のようで、信号ハンドラがいくつかの例で得られる関数と似ていると思います。
(b)「その男は何をしていますか?」と思っている人のために:この種のものをより良く解決する方法についてアドバイスをしていますか?
ちょうど好奇心から、なぜあなたはスレッドを使いたくないですか?私はブーストをまったく使用していませんが、私の前提では、コールバック関数が提供されることを期待しています。 – M4rc
スレッド内で '' Foo :: run() ''を起動し、 '' main''でシグナルを捕捉し、メインコールをsthにします。 '' thread.terminate() ''のように?はい、可能性はありますが、これはあまりにも多いと思いました。 –
それは確かに一つの方法です。もう1つは(私の鎮静化した思考の中で)、あなたが必要とする情報を持つ構造体をスレッドとして登録することができるので、通常のメイン関数をループして実行するシグナルハンドラそれが自分のスレッドであれば、値byrefを取得してイベントが発生したかどうかを確認し、そうであればどのようなイベントと適切なレスポンスを返します。 – M4rc