优雅地终止基于Boost Asio的Windows控制台应用程序 [英] Gracefully terminate a Boost Asio based Windows console application

查看:206
本文介绍了优雅地终止基于Boost Asio的Windows控制台应用程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在基于boost.asio的HTTP服务器上工作.它应该在外部停止.我们使用了asio信号处理,它对于ctrl-c很好用,但是不能处理WM_CLOSE,因此没有直接的方法可以从外部正常关闭应用程序,例如通过taskkill.强制终止该过程不是一种选择.有已知的方法吗?

I am working on a boost.asio based HTTP server. It is supposed to be stopped externally. We use asio signal handling, and it works well for ctrl-c, but does not handle WM_CLOSE, so there is no straightforward way to gracefully close the application externally, e.g. via taskkill. Terminating the process forcibly is not an option. Is there a known approach to this?

推荐答案

更新

只需使用您通常会使用"的任何IPC方法

Just use any IPC method you would "normally" use

  1. 编写一个简单的过程控制实用程序,例如 named_condition 表示您的asio进程已关闭.

  1. Write a simple process control utility that uses e.g. named_condition to signal your asio process to shutdown.

请注意,如果您认为此固有于平台的特定代码段更简单,则named_codition等效于Win32命名事件

Note that named_codition is somewhat equivalent to a Win32 Named Event in case you think that simpler for this inherently platform specific piece of code

考虑制作一个 Windows服务(NTService) ,就像你想要的那样

Consider making a Windows Service (NTService), as it looks like this is what you want


原始答案 ,涉及如何监听控制台关闭事件:

Original answer, dealing with how to listen for console close events:

这实际上与使用Boost Asio没有关系.当然,在POSIX平台上,您可以使用boost::asio::signal_set处理SIG_INT和SIG_TERM信号.

This is really not related to using Boost Asio. Of course, on POSIX platforms you could use boost::asio::signal_set to handle the SIG_INT and SIG_TERM signals.

但是,您在Windows上,并且没有可移植的方式来检测控制台关闭事件.

However, you're on windows, and there is no portable way to detect console close event.

您应该编写一个控制台处理程序例程,以检测CTRL_CLOSE_EVENT(如果需要,还可以检测CTRL_C_EVENT),并使用SetConsoleCtrlHandler将处理例程添加到您的进程中.

You should write a console handler routine that detects CTRL_CLOSE_EVENT (and CTRL_C_EVENT, if desired), and use SetConsoleCtrlHandler to add the handler routine to your process.

#include <windows.h> 
#include <stdio.h> 

BOOL CtrlHandler( DWORD fdwCtrlType ) 
{ 
  switch( fdwCtrlType ) 
  { 
    // Handle the CTRL-C signal. 
    case CTRL_C_EVENT: 
      printf( "Ctrl-C event\n\n" );
      Beep( 750, 300 ); 
      return( TRUE );

    // CTRL-CLOSE: confirm that the user wants to exit. 
    case CTRL_CLOSE_EVENT: 
      Beep( 600, 200 ); 
      printf( "Ctrl-Close event\n\n" );
      return( TRUE ); 

    // Pass other signals to the next handler. 
    case CTRL_BREAK_EVENT: 
      Beep( 900, 200 ); 
      printf( "Ctrl-Break event\n\n" );
      return FALSE; 

    case CTRL_LOGOFF_EVENT: 
      Beep( 1000, 200 ); 
      printf( "Ctrl-Logoff event\n\n" );
      return FALSE; 

    case CTRL_SHUTDOWN_EVENT: 
      Beep( 750, 500 ); 
      printf( "Ctrl-Shutdown event\n\n" );
      return FALSE; 

    default: 
      return FALSE; 
  } 
} 

int main( void ) 
{ 
  if( SetConsoleCtrlHandler( (PHANDLER_ROUTINE) CtrlHandler, TRUE ) ) 
  { 
    printf( "\nThe Control Handler is installed.\n" ); 
    printf( "\n -- Now try pressing Ctrl+C or Ctrl+Break, or" ); 
    printf( "\n    try logging off or closing the console...\n" ); 
    printf( "\n(...waiting in a loop for events...)\n\n" ); 

    while( 1 ){ } 
  } 
  else 
  {
    printf( "\nERROR: Could not set control handler"); 
    return 1;
  }
return 0;
}

要与Boost Asio协调,可以使处理程序停止(全局)io_service对象,并可能为运行的动作设置一些标志.最后,您可能需要取消飞行中的所有异步操作(例如deadline_timer s).

To coordinate with Boost Asio, you could have the handler stop the (global) io_service object and perhaps set some flag for running actions. Finally, you may have to cancel any async operations in flight (e.g. deadline_timers).

一旦这样做,它应该很干净.

Once you did that, it should be pretty clean.

这篇关于优雅地终止基于Boost Asio的Windows控制台应用程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆