我有一個對象,它在無限循環中做了一些工作。 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
它被捕獲並會導致我的對象停止迭代並返回主菜單。
我現在有兩個問題:
(一)在你看到標有「編譯器抱怨」一行代碼,消息就像
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
什麼我需要改變,以使這項工作?我認爲f
就像void f(int)
,就像信號處理程序在某些示例中獲得的功能一樣。
(b)對於那些想知道「那個人在幹什麼?」的人:你有什麼建議可以更好地解決這種問題嗎?
出於好奇,爲什麼你不想使用線程?雖然我根本沒有使用boost,但我的假設是期望提供一個回調函數。 – M4rc
就像在線程中啓動''Foo :: run()''一樣,在main函數中捕獲信號並讓主函數調用。像''thread.terminate()''?是的,會是一種可能性,但我認爲這樣做太多了。 –
這是確定的一種方法。另一個(在我思考的沉悶mi)中)是,你可以擁有一個結構,包含你需要的任何信息,把它註冊爲一個線程,所以你用它的正常主函數運行循環,並且運行信號處理程序在它自己的線程上,那麼你只需抓取值byref來查看事件是否發生,如果是的話,是什麼事件和適當的響應。 – M4rc