Ice笔记--Ice信号处理机制

Ice信号处理机制

概述

信号(signal)是一种进程间通信机制,它给应用程序提供了一种异步的软件中断,使应用程序有机会接受其他程序或者终端发出的命令(信号)。应用程序接收到信号后,一般有三种处理方式:忽略,默认,或者捕捉。如果我们自定义了信号处理函数,那么程序将会执行该信号的处理函数。

Ice::Application类提供了ice runtime的通信器初始化与信号捕获处理功能,适合在用户进程中使用。同时Ice也提供了Ice::Service类,相对于Ice::Application它更适用的情况是:应用程序需要作为Unix守护进程(daemon)运行在系统中。

下面将简单介绍这方面的内容。


Ice所能捕获的信号

在Ice run time中,支持三种linux信号的捕获:SIGINT,SIGHUP,SIGTERM。

1)SIGHUP:当终端发现断线情况时发送给与控制终端相连的控制进程的信号,或控制进程运行结束时发出的信号。它通常用来通知守护进程重新读取系统配置文件。
2)SIGINT:进程中断信号,可以用来中断一个正在运行的进程。通常是从终端输入的中断指令,如Ctrl+C键或Delete键。

3) SIGTERM:调用kill(1)命令时缺省产生的信号。

Application类中的信号处理


1.信号处理方法在Application类中的声明

Application.h中关于信号处理的函数定义如下:

// Application的入口函数,提供了丰富的初始化方式,一般使用第一个
// 将应用主函数参数直接传入即可
int main(int, char*[]);
int main(int, char*[], const char*);
int main(int, char*[], const Ice::InitializationData&);
int main(int, char*[], const char*, const Ice::LoggerPtr&);
int main(const StringSeq&);
int main(const StringSeq&, constchar*);
int main(const StringSeq&, constIce::InitializationData&);
// 应用的执行循环,应用需要继承这个函数并用自己的逻辑重写
virtual int run(int, char*[]) = 0;
 
// 信号回调函数
// 如果需要自己对信号进行处理,则需要继承和改写这个函数
// 注意,需在run()函数中调用callbackOnInterrupt()来向Ice表示使用用户回调
// 该函数的默认实现是空函数
virtual void interruptCallback(int);
 
// 返回应用名,即argv[0]
static const char* appName();
 
// 返回当前使用的Ice通信器实例指针
static CommunicatorPtr communicator();
 
// 设置信号处理模式
//
// 销毁模式:信号到来时将通信器实例销毁,也是Application的默认模式
static void destroyOnInterrupt();
 
// 关闭模式:信号到来时将通信器实例关闭,但不销毁
static void shutdownOnInterrupt();
 
// 忽略模式:信号到来时将通信器不做任何处理
static void ignoreInterrupt();
 
// 用户模式:信号到来时将调用interruptCallback()函数
static void callbackOnInterrupt();
 
// 信号的阻止和放开,不常用
// 阻塞信号的到来
static void holdInterrupt();
 
// 放开被阻塞的信号
static void releaseInterrupt();
 
// Application当前是否被信号中断
// 可用于判断Application的结束是否由于信号造成
static bool interrupted();

2.使用用户模式信号处理方法的示例:

#include <Ice/Application.h>
#include <iostream>
using namespace std;
 
class MyApplication : virtualpublic Ice::Application
{
public:
    virtual int run(int argc , char* argv[])
    {
       //ignoreInterrupt(); //1.该方法设置信号处理模式为:忽略模式
 
        //2.callbackOnInterrupt:用户模式,信号到来时调用interruptCallback方法
        //如果不使用此方法,程序将会进行默认的信号处理。
        callbackOnInterrupt();
        interruptCallback(argc);
        //More Server code here...
    }
virtual void interruptCallback(int signo)
{
       cout<<"Enter the interruptCallback()"<<endl;
       if(signo== SIGINT)
       {
           cout<<"receive the signal SIGINT"<<endl;
           //TODO:
       }
       else if(signo== SIGHUP)
       {
           cout<<"receive the signal SIGHUP"<<endl;
           //TODO:
       }
       else if(signo== SIGTERM)
       {
           cout<<"receive the signal SIGTERM"<<endl;
           //TODO:
       }
       else{cout<<"receivea signal:"<<signo<<endl;}
}   
//More code here...
};


Service类的信号处理


1.Service类与Application类的异同

1)Ice::Application与Ice::Service功能相似,但Ice::Service类还封装了比较低级的,针对特定平台的初始化与关闭的步骤---系统服务常常需要这样的步骤。

2)Ice::Service需要用户继承的核心函数为start(),而Ice::Application需要用户继承的核心函数是run().虽然Ice::Service也有一个run()函数,但在Ice::Service中服务必须在start()函数中启动,比如处理命令行参数,创建对象适配器,注册servants等。

3)Ice::Service隐含了对Service的结束(通过run()方法调用WaitForShutdown()),而Ice::Application需要显式的定义类似ic->waitForShutdown()的操作。

2.信号处理方法在Ice::Service类中的声明

class ICE_API Service
{
public:
    Service();
    virtual ~Service();
 
    // 关闭服务,默认操作是关闭服务所使用的Ice通信器
    // 如果你需要其它的附加操作,继承并改写此函数
    virtual bool shutdown();
 
    // 信号回调函数,表示Service被信号所中断,默认操作是调用shutdown()函数
    virtual void interrupt();
 
    // 供给IceUtil::CtrlHandler注册的原始信号处理函数
    // 它处理完SIGHUP后调用interrupt。一般无需继承和改写,除非你想自己处理SIGHUP
    virtual void handleInterrupt(int);
 
protected:
   // 允许子类执行它的启动活动,比如扫描所提供的参数向量、识别命令行选项,创建对象// 适配器,以及注册servants。
    // 如果启动成功,子类必须返回true,否则返回false。
    // 一般必须继承,并在其中实现应用自己的应用逻辑。
    virtual bool start(int, char*[]) = 0;
 
    // 阻塞等待Service的关闭。缺省操作是调用Ice通信器的waitForShutdown()。
    virtual void waitForShutdown();
 
    // 服务停止清理函数。决定了main()的返回值,缺省操作返回true。
    // 如果你有其它资源需要清理,需要继承并改写该函数。
    virtual bool stop();
 
    // 初始化Service所用的Ice通信器
    // Service类提供了一个方法让用户决定Ice通信器的构造方式
    virtual Ice::CommunicatorPtr initializeCommunicator(int&, char*[], const InitializationData&);
 
    // 日志相关函数
    virtual void syserror(const std::string&);
    virtual void error(const std::string&);
    virtual void warning(const std::string&);
    virtual void trace(const std::string&);
    virtual void print(const std::string&);
 
public:
 
    // 服务入口函数,处理服务安装、卸载和run()的调用
    int main(int&, char*[], const InitializationData&= InitializationData());
    int main(StringSeq&, constInitializationData& = InitializationData());
    //
    // 返回服务使用的Ice通信器
    Ice::CommunicatorPtrcommunicator() const;
    //
    // 返回服务的惟一实例,注意实例是静态提供的。
    static Service* instance();
    //
    // 判断当前运行模式。如果是以Win32服务或linux daemon方式运行,返回true.
    // 否则返回false
    bool service() const;
 
    // 返回当前Service名字,等同于Ice::Application::appName()
    std::string name() const;
 
    // 检查当前平台是否支持后台运行(win32服务/linux daemon)
    bool checkSystem()const;
 
    // Service的真正执行函数  
    int run(int&, char*[], const InitializationData&= InitializationData());
 
protected:
    // 允许信号中断
    void enableInterrupt();
    // 禁止信号中断
    void disableInterrupt();
 
private:
 
    Ice::LoggerPtr _logger;    // Service使用的Log对象
    Ice::CommunicatorPtr_communicator; //Services使用的通信器
    bool _nohup;        // 是否忽略SIGHUP函数
    bool _service;        // Service运行模式是否为服务/daemon
    std::string _name;    //  Service应用名
 
    static Service* _instance; // Service的惟一静态实例
};

3.用法举例

class MyService : publicIce::Service
{
protected:
    virtual bool start(int, char *[],int&);   //一般要覆盖基类的start,stop,interrupt这三种方法
    virtual bool stop();
    virtual void interrupt();
    virtual void handleInterrupt(int);//在需要自定义处理信号情况下才需要覆盖这个方法
private:
    Ice::ObjectAdapterPtrm_adapter;
};
 
void MyService::interrupt()
{
    std::cout<< "Receive signal ..."<< std::endl;
    //TODO:
}
 
bool MyService::stop()
{
    std::cout<< "Stop running ..."<< std::endl;
    //TODO:
    return true;
}
 
void MyService::handleInterrupt(int signo)
{
    interrupt();
    if(signo==SIGHUP){
        cout<<"signal:SIGHUP"<<endl;
       //TODO:
   }
    else if(signo==SIGINT){
        cout<<"signal:SIGINT"<<endl;
       //TODO:
   }
    else if(signo==SIGTERM){
        cout<<"signal:SIGTERM"<<endl;
       //TODO:
   }
    else {
cout<<"Unknown signal."<<endl;
//TODO:
   }
    //TODO:
}
 
bool MyService::start(int argc, char * argv[],int& status)
{
    enableInterrupt();//设置信号中断模式
    //TODO:
    //communicator()->waitForShutdown(); //不需要显示进行这个操作
    return true;
}

参考自:http://blog.youkuaiyun.com/ydogg/article/details/1873854


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值