Tôi có một đối tượng hoạt động trong vòng lặp vô tận. Các main()
instantiates đối tượng và gọi phương thức run()
. Vì tôi không muốn sử dụng các chủ đề, tôi cần một giải pháp để làm cho đối tượng của tôi ngừng chạy. Dưới đây bạn thấy những gì tôi đã đưa ra.Nhận tín hiệu: Sử dụng chức năng thành viên làm bộ xử lý tín hiệu
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;
}
};
Như bạn thấy, tôi cần gửi tín hiệu không đồng bộ. Do đó, tôi sử dụng trình xử lý tín hiệu và sigaction
. Bên dưới main
Tôi có thể tưởng tượng để sử dụng.
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();
}
Những gì tôi mong chờ bây giờ: Chương trình chạy cho đến khi tôi gửi SIGTERM
được bắt và sẽ gây ra đối tượng của tôi ngừng lặp đi lặp lại và trở về chính.
Tôi có hai câu hỏi bây giờ:
(a) Trong đoạn mã bạn thấy dòng chữ được đánh dấu bằng "biên dịch phàn nàn", thông điệp giống như
boost::function<void(int)> cannot be converted to __sighandler_t {aka void (*)(int)}
gì tôi cần phải thay đổi để làm cho công việc này? Tôi nghĩ rằng f
giống như void f(int)
, giống như các chức năng mà trình xử lý tín hiệu nhận được trong một số ví dụ.
(b) Đối với những người bạn thắc mắc "anh chàng đó đang làm gì vậy?": Bạn có lời khuyên nào để giải quyết vấn đề này tốt hơn không?
Chỉ vì tò mò, tại sao bạn không muốn sử dụng đề tài?Mặc dù tôi đã không sử dụng tăng ở tất cả, giả định của tôi nó mong đợi một chức năng gọi lại được cung cấp. – M4rc
Giống như bắt đầu '' Foo :: run() '' trong một luồng, bắt tín hiệu trong '' chính'' và để cho lệnh gọi chính là sth. như '' thread.terminate() ''? Có, sẽ là một khả năng, nhưng tôi nghĩ rằng nó sẽ là quá nhiều cho việc này. –
Đó là một cách chắc chắn. Cái khác mà (trong thiên hướng an thần của tôi) là bạn có thể có cấu trúc với bất kỳ thông tin nào bạn cần, đăng ký nó như một luồng, vì vậy bạn chạy vòng lặp với các hàm chính bình thường trong đó, và trình xử lý tín hiệu đang chạy trên chỉ riêng của nó, sau đó bạn chỉ cần lấy giá trị byref để xem một sự kiện đã xảy ra, và nếu có sự kiện nào và phản hồi thích hợp. – M4rc