ACE信号はノットを使用する


1、 ACE_Sig_Action
ACE_Sig_Actionは、POSIX sigaction()呼び出しをカプセル化するカプセル化クラスである.ACE_の使用Sig_Actionクラスでは、1つの信号に1つのコールバック関数しか設定できません.コールバック関数は、信号割り込み処理コンテキストにあるため、コールバック関数で時間をかけて動作しないでください.時間がかかる仕事があればACEを使うことができます.Reactorの通知メカニズムは、時間のかかる仕事を普通の実行コンテキストに移籍させる.
ACE_Sig_アクションの使用方法:
  • は、typedef void(*ACE_SignalHandler)(int);voidを返し、intタイプのパラメータ(信号タイプ値)を受け入れる.
  • ACEのインスタンス化Sig_Actionオブジェクト、ACE_を使用Sig_Action::handler(ACE_SignalHandler)関数コールバック関数を設定し、ACE_を使用Sig_Action::register_Action(int signum)関数で、信号signumにコールバック関数を設定します.

  • サンプルコード:
    void my_handler (int signo) {
        // Do something
    }
    
    ACE_Sig_Action sig_action;
    sig_action.handler (my_handler);
    sig_action.register_action (SIGUSR1);

    信号割り込みコールバック関数の実行中も、
    他の信号は中断されますが、処理中の信号では中断できません.ある信号のコールバック処理実行中に複数回この信号を受信した場合、オペレーティングシステムはpendこの信号を、前の処理関数の実行が完了した後、コールバックする
    一度.信号コールバック関数が中断されたくない場合はACE_Sig_Actionインスタンスは、信号マスクを指定します.上記の例のコードのように、SIGUSR 1信号の割り込み処理関数を信号SIGUSR 2によって割り込ませたくない場合は、register_Action()メソッド呼び出しの前に次のコードを追加します.
    ACE_Sig_Set sig_set;
    sig_set.add (SIGUSR2);
    sig_action.mask (sig_set);

    なお、我々の多くのブロックされたシステム呼び出しは、信号を使用する際に、ブロック関数の信号中断処理を行うために、信号によって中断されることができる.sigaction()システム呼び出しのためのSA_の提供RESTARTフラグがサポートするシステムは、ACE_Sig_Actionオブジェクト設定SA_RESTARTフラグは、信号によって中断されたシステム呼び出しを継続させることができる.ただし、このIDを設定すると機能するかどうかは、オペレーティングシステムのドキュメントを参照してください.私は自分のlinux仮想マシンでこのIDを設定したとき、信号が中断されたシステム呼び出しを自動的に再呼び出しませんでした.
    2、 ACE_Sig_Handler
    ACE_Sig_Handlerは、オブジェクト向けのイベントプロセッサベースの信号登録および割り当てスキームを提供する.ACE_の使用Sig_Handlerが提供するこの案はACEからEvent_Handlerの派生信号処理クラス.
    2.1 ACE_Sig_Handlerの使い方:
  • ACEからEvent_Handlerは信号処理クラスを派生して、虚の方法handle_を実現しますsignal().
  • 信号処理クラスインスタンスを作成し、ACE_を作成するSig_Handlerインスタンス.ACE_を呼び出すSig_Handler::register_handler(int signo,ACE_Event_Handler*h)メソッドは、信号に信号プロセッサを設定する.

  • 2.2サンプルコード
    #include <ace/Sig_Handler.h>
    #include <ace/Event_Handler.h>
    #include <ace/Log_Msg.h>
    #include <ace/Process.h>
    
    class MySignalHandler: public ACE_Event_Handler
    {
        public:
            MySignalHandler (int signo): signum_(signo) {}
    
            virtual ~MySignalHandler () {}
    
            virtual int handle_signal (int signum,
                    siginfo_t * = 0,
                    ucontext_t * = 0)
            {
                ACE_TRACE (ACE_TEXT ("MySignalHandler::handle_signal"));
    
                // Make sure the right handler was called back.
                ACE_ASSERT (signum == this->signum_);
    
                ACE_DEBUG ((LM_DEBUG,
                            ACE_TEXT ("%S occured
    "), signum)); return 0; } private: int signum_; }; int ACE_TMAIN (int argc, ACE_TCHAR *argv[]) { MySignalHandler h1 (SIGUSR1), h2 (SIGUSR2); ACE_Sig_Handler handler; handler.register_handler (SIGUSR1, &h1); handler.register_handler (SIGUSR2, &h2); //ACE_OS::kill (ACE_OS::getpid (), SIGUSR1); //ACE_OS::kill (ACE_OS::getpid (), SIGUSR2); ACE_Process kill_signal; ACE_Process_Options options; options.command_line ("./kill_signal %d %d", ACE_OS::getpid (), SIGUSR1); kill_signal.spawn (options); options.command_line ("./kill_signal %d %d", ACE_OS::getpid (), SIGUSR2); kill_signal.spawn (options); int time = 10; while (ACE_OS::sleep (time) == -1) { ACE_DEBUG ((LM_DEBUG, ACE_TEXT ("Sleep() returns -1
    "))); if (errno == EINTR) continue; else { ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p
    "), ACE_TEXT ("sleep")), -1); } } return 0; }
    kill_Signalは、指定プロセスIDに指定信号を送信するウィジェットである.プログラムは子供を派遣するプロセスで自分に信号を送信します.
    handle_Signalの最初のパラメータは、割り込みの信号値を開始する.詳しくは説明しませんhandle_Signalコールバック関数の他の2つのパラメータは、オペレーティングシステムのドキュメントを参照できます.ここでsiginfo_tは、送信中の信号の起因や属性などの情報を提供する.
    3、 ACE_Sig_Guard
    信号割り込み処理は非同期である.あるコードの実行中に信号に中断されたくない場合は、ACE_を使用します.Sig_Guardは保護します.
    サンプルコードは次のとおりです.
    ACE_Sig_Set sig_set;
    sig_set.add (SIGUSR1);
    sig_set.add (SIGUSR2);
    
    {
        ACE_Sig_Guard sig_guard (&sig_set); // Start of protection
        // Protected Code.
        // Can't interrupt by signals in sig_set
    } //End of protection
    保護コードの実行中にsig_setの信号が送信されると、保護コードが実行された後にのみ、信号中断処理関数がコールバックされる.