【问题标题】:gSoap: how to gracefully shutdown the webservice application?gSoap:如何优雅地关闭 Web 服务应用程序?
【发布时间】:2011-03-08 21:52:04
【问题描述】:

我正在使用 gSoap 编写网络服务。它作为控制台应用程序运行。在我看到的所有 gSoap 示例中,即使在多线程版本中,请求也会像 for(;;;) 这样在无限循环中分派。

但是,当用户按下控制台上的空格键时,如何让我的 Web 服务正常终止?

最好:

  1. 停止接受新连接;
  2. 为现有的服务;
  3. 退出应用程序

【问题讨论】:

  • 您在寻找逻辑还是源代码?
  • 任何可以帮助我理解如何做到这一点的东西。首选代码,但我并不愚蠢,我想我会在这个主题上只用一两个词就可以了;)现在我只是从 kbhit()=true 的循环中中断并等待几秒钟要求完成。但这并不可靠。如果某个线程需要更长的时间才能完成怎么办?

标签: c++ web-services soap gsoap


【解决方案1】:

到目前为止,我想出的唯一解决方案是使用超时 肥皂->recv_timeout = 20; 肥皂->send_timeout = 20; 肥皂->连接超时= 5; 肥皂->接受超时= 5; 然后所有阻塞函数定期返回。但这对我来说并不理想,因为我希望即使有正在进行的传输也能够快速终止应用程序,但同时,不想在缓慢/不稳定的连接上损害可靠性(它是嵌入式通过 GPRS 连接的设备)。

【讨论】:

    【解决方案2】:

    文档中的7.2.4 How to Create a Multi-Threaded Stand-Alone Service 部分包含编写接受循环的示例代码。您需要编写自己的接受循环并添加信号处理,以便它响应 Ctrl-C。

    1. 停止接受新连接:

      离开循环,这样你就停止调用accept。

    2. 服务现有的:

      线程需要在完成时通知您,因此您可以在活动客户端数量为零时退出。 (boost::thead_group 有一个 join_all 正是这样做的。)

    3. 退出应用程序:

    【讨论】:

    • 不幸的是,Eddy 的解决方案对我不起作用。 soap_accept 似乎没有退出信号。在调用soap_accept 之前,我在soap.master 上添加了选择。当接收到信号时,选择将用 EINTR 中止,然后我可以拿起并使用它来退出进程。如果选择返回成功,那么我就像以前一样调用soap_accept。 HTH。
    【解决方案3】:

    您需要做的是注册信号处理程序,因此当您使用 Ctrl + C 终止应用程序时,它会调用您注册的函数,您可以在其中优雅地终止。

    例如

    class gsoap_test {
    
    public:
       void start() {
         running_ = true;
         while(running_) {
           //gsoap threads
         }
         //stop and cleanup
       }
    
    
       void stop() {
            running_ = false;
       }
     private:
          bool running_;
    };
    
     //global variable 
     gsoap_test gsoap;
    
    
    void sighandler(int sig)
    {
        std::cout<< "Signal caught..." << std::endl;
    
        //Stop gracefully here
        gsoap.stop();
        exit(0);
    
    }
    
    int main(int argc, char** argv) {
    
      //register signal
       signal(SIGABRT, &sighandler);
       signal(SIGTERM, &sighandler);
       signal(SIGINT, &sighandler);
    
       gsoap.start();
    
       return EXIT_SUCCESS;
    }
    

    【讨论】:

    • 嗯,问题是如何优雅地终止 gSOAP 线程,而不仅仅是如何通过 CTRL-C 或其他方式终止应用程序。我现在通过检查 kbhit 来终止。
    • 您可以停止该函数中的线程。我对我的 muktithreading sip 服务器使用相同的功能,我们需要优雅地停止调用。
    • 查看上面使用 gsoap_test 类的编辑。 gsoap_test 的对象也可以作为函数 args 传递给 sighandler 函数,如果您不想使其成为全局对象。其他选项是使用 boost::signal 函数。
    • 嗯,是的,但这与@Eddy Pronk 建议的方法相同,对吧?
    猜你喜欢
    • 2010-09-06
    • 2015-10-01
    • 1970-01-01
    • 1970-01-01
    • 2018-03-11
    • 2016-06-09
    • 1970-01-01
    • 2021-10-28
    相关资源
    最近更新 更多