建立一個可正常結束的Proactor伺服器

來源:互聯網
上載者:User

這是APG上關於Proactor使用的例子,去掉了trace資訊,做了一點小修改:

CODE:


#include <ace/Os_main.h>
#include <ace/Asynch_Acceptor.h>
#include <ace/Proactor.h>
#define LISTEN_PORT 5222

class HA_Proactive_Service : public ACE_Service_Handler
{
public:
       ~HA_Proactive_Service ()
       {
              if (this->handle () != ACE_INVALID_HANDLE)
                     ACE_OS::closesocket (this->handle ());
       }

       virtual void open (ACE_HANDLE h, ACE_Message_Block&)
       {
              this->handle (h);
              if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0   )
              {
                     delete this;
                     return;
              }

              ACE_Message_Block *mb;
              ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));
              if (this->reader_.read (*mb, mb->space ()) != 0)
              {
                     mb->release ();
                     delete this;
                     return;
              }
       }

       virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)
       {
              ACE_Message_Block &mb = result.message_block ();
              if (!result.success () || result.bytes_transferred () == 0)
              {
                     mb.release ();
                     delete this;
              }
              else
              {
                     ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Received Data : %c/n"), *mb.rd_ptr()));
                     mb.release();

                     ACE_Message_Block *new_mb;
                     ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));
                     this->reader_.read (*new_mb, new_mb->space ());
              }
       }

       virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)
       { result.message_block ().release (); }

private:
       ACE_Asynch_Read_Stream reader_;
       ACE_Asynch_Write_Stream writer_;
};

class HA_Proactive_Acceptor : public ACE_Asynch_Acceptor<HA_Proactive_Service>
{
};

int ACE_TMAIN (int, ACE_TCHAR *[])
{
       ACE_INET_Addr listen_addr( LISTEN_PORT );
       HA_Proactive_Acceptor aio_acceptor;
       if (0 != aio_acceptor.open (listen_addr, 0, 0, 5, 1, 0, 0))
              ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p/n"), ACE_TEXT ("acceptor open")), 1);

       ACE_Proactor::instance ()->proactor_run_event_loop ();

       return 0;
}

程式在5222連接埠上監聽,對於每個已建立的串連,伺服器將所有收到的資料列印到控制台上。這就是整個程式所實現的功能。
但是這個程式存在一個很大的問題:沒有辦法正常結束。當運行這個程式後,只能強制結束這個進程,因為程式沒有提供從proactor事件迴圈中退出來的方法。
讓程式能夠正常退出是很有必要的,比如在進行記憶體流失的檢測時,如果程式沒有辦法正常退出,那麼記憶體流失的檢測工作將很難進行。

為了實現能夠正常關閉程式的目的,需要稍微修改一下上面的程式實現。
這次程式將會有兩個線程在運行,一個是Proactor事件迴圈線程,另一個則為控制線程。在控制線程中,要能夠關閉Proactor線程,然後將程式乾淨地退出。
得益於ACE強大的封裝,所做的改動並不大:

CODE:


class ProactorThread : public ACE_Task_Base
{
public:
       int open()
       {
              return this->activate();
       }

       int close()
       {
              ACE_Proactor::instance()->proactor_end_event_loop();
              this->wait();
              return 0;
       }

       virtual int svc()
       {
              ACE_INET_Addr listen_addr( LISTEN_PORT );
              HA_Proactive_Acceptor aio_acceptor;
              if (0 != aio_acceptor.open (listen_addr, 0, 0, 5, 1, 0, 0))
                     ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p/n"), ACE_TEXT ("acceptor open")), 1);

              ACE_Proactor::instance ()->proactor_run_event_loop ();
              ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Thread ended/n")));

              return 0;
       }
};

int ACE_TMAIN (int, ACE_TCHAR *[])
{
       ProactorThread thread;
       thread.open();

       int x;
       std::cin >> x;

       thread.close();

       return 0;
}

僅僅只是添加了一個新的類,用於封裝Proactor事件迴圈線程,另外修改了程式的主函數。這次程式將首先建立一個Proactor事件迴圈線程,然後主線程等待使用者輸入任意數後結束Proactor線程,在Proactor線程正常退出後主線程退出。

注意這裡有兩個要點:
1.當執行proactor_end_event_loop()之後,Proactor線程是從proactor_run_event_loop()處退出,所以會接著執行下面的代碼,列印出” Thread ended”資訊。
2.主線程必須使用wait()等待Proactor線程正常結束後再退出,否則如果主線程退出後,Proactor線程仍有一些資源釋放工作未完成,那麼就會存在資源未正確釋放的問題。

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.