创建一个可正常结束的Proactor服务器

这是APG上关于Proactor使用的例子,去掉了trace信息,做了一点小修改:

<o:p></o:p>

#include <ace/Os_main.h><o:p></o:p>

#include <ace/Asynch_Acceptor.h><o:p></o:p>

#include <ace/Proactor.h><o:p></o:p>

#define LISTEN_PORT 5222<o:p></o:p>

<o:p></o:p>

class HA_Proactive_Service : public ACE_Service_Handler<o:p></o:p>

{<o:p></o:p>

public:<o:p></o:p>

       ~HA_Proactive_Service ()<o:p></o:p>

       {<o:p></o:p>

              if (this->handle () != ACE_INVALID_HANDLE)<o:p></o:p>

                     ACE_OS::closesocket (this->handle ());<o:p></o:p>

       }<o:p></o:p>

<o:p></o:p>

       virtual void open (ACE_HANDLE h, ACE_Message_Block&)<o:p></o:p>

       {<o:p></o:p>

              this->handle (h);<o:p></o:p>

              if (this->reader_.open (*this) != 0 || this->writer_.open (*this) != 0   )<o:p></o:p>

              {<o:p></o:p>

                     delete this;<o:p></o:p>

                     return;<o:p></o:p>

              }<o:p></o:p>

<o:p></o:p>

              ACE_Message_Block *mb;<o:p></o:p>

              ACE_NEW_NORETURN (mb, ACE_Message_Block (1024));<o:p></o:p>

              if (this->reader_.read (*mb, mb->space ()) != 0)<o:p></o:p>

              {<o:p></o:p>

                     mb->release ();<o:p></o:p>

                     delete this;<o:p></o:p>

                     return;<o:p></o:p>

              }<o:p></o:p>

       }<o:p></o:p>

<o:p></o:p>

       virtual void handle_read_stream (const ACE_Asynch_Read_Stream::Result &result)<o:p></o:p>

       {<o:p></o:p>

              ACE_Message_Block &mb = result.message_block ();<o:p></o:p>

              if (!result.success () || result.bytes_transferred () == 0)<o:p></o:p>

              {<o:p></o:p>

                     mb.release ();<o:p></o:p>

                     delete this;<o:p></o:p>

              }<o:p></o:p>

              else<o:p></o:p>

              {<o:p></o:p>

                     ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Received Data : %c\n"), *mb.rd_ptr()));<o:p></o:p>

                     mb.release();<o:p></o:p>

<o:p></o:p>

                     ACE_Message_Block *new_mb;<o:p></o:p>

                     ACE_NEW_NORETURN (new_mb, ACE_Message_Block (1024));<o:p></o:p>

                     this->reader_.read (*new_mb, new_mb->space ());<o:p></o:p>

              }<o:p></o:p>

       }<o:p></o:p>

<o:p></o:p>

       virtual void handle_write_stream (const ACE_Asynch_Write_Stream::Result &result)<o:p></o:p>

       { result.message_block ().release (); }<o:p></o:p>

<o:p></o:p>

private:<o:p></o:p>

       ACE_Asynch_Read_Stream reader_;<o:p></o:p>

       ACE_Asynch_Write_Stream writer_;<o:p></o:p>

};<o:p></o:p>

<o:p></o:p>

class HA_Proactive_Acceptor : public ACE_Asynch_Acceptor<HA_Proactive_Service><o:p></o:p>

{<o:p></o:p>

};<o:p></o:p>

<o:p></o:p>

int ACE_TMAIN (int, ACE_TCHAR *[])<o:p></o:p>

{<o:p></o:p>

       ACE_INET_Addr listen_addr( LISTEN_PORT );<o:p></o:p>

       HA_Proactive_Acceptor aio_acceptor;<o:p></o:p>

       if (0 != aio_acceptor.open (listen_addr, 0, 0, 5, 1, 0, 0))<o:p></o:p>

              ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("acceptor open")), 1);<o:p></o:p>

<o:p></o:p>

       ACE_Proactor::instance ()->proactor_run_event_loop ();<o:p></o:p>

<o:p></o:p>

       return 0;<o:p></o:p>

}<o:p></o:p>

<o:p></o:p>

程序在5222端口上监听,对于每个已建立的连接,服务器将所有收到的数据打印到控制台上。这就是整个程序所实现的功能。

但是这个程序存在一个很大的问题:没有办法正常结束。当运行这个程序后,只能强制结束这个进程,因为程序没有提供从proactor事件循环中退出来的方法。

让程序能够正常退出是很有必要的,比如在进行内存泄漏的检测时,如果程序没有办法正常退出,那么内存泄漏的检测工作将很难进行。

<o:p></o:p>

为了实现能够正常关闭程序的目的,需要稍微修改一下上面的程序实现。

这次程序将会有两个线程在运行,一个是Proactor事件循环线程,另一个则为控制线程。在控制线程中,要能够关闭Proactor线程,然后将程序干净地退出。

得益于ACE强大的封装,所做的改动并不大:

<o:p></o:p>

class ProactorThread : public ACE_Task_Base<o:p></o:p>

{<o:p></o:p>

public:<o:p></o:p>

       int open()<o:p></o:p>

       {<o:p></o:p>

              return this->activate();<o:p></o:p>

       }<o:p></o:p>

<o:p></o:p>

       int close()<o:p></o:p>

       {<o:p></o:p>

              ACE_Proactor::instance()->proactor_end_event_loop();<o:p></o:p>

              this->wait();<o:p></o:p>

              return 0;<o:p></o:p>

       }<o:p></o:p>

<o:p></o:p>

       virtual int svc()<o:p></o:p>

       {<o:p></o:p>

              ACE_INET_Addr listen_addr( LISTEN_PORT );<o:p></o:p>

              HA_Proactive_Acceptor aio_acceptor;<o:p></o:p>

              if (0 != aio_acceptor.open (listen_addr, 0, 0, 5, 1, 0, 0))<o:p></o:p>

                     ACE_ERROR_RETURN ((LM_ERROR, ACE_TEXT ("%p\n"), ACE_TEXT ("acceptor open")), 1);<o:p></o:p>

<o:p></o:p>

              ACE_Proactor::instance ()->proactor_run_event_loop ();<o:p></o:p>

              ACE_DEBUG ((LM_DEBUG, ACE_TEXT("Thread ended\n")));<o:p></o:p>

<o:p></o:p>

              return 0;<o:p></o:p>

       }<o:p></o:p>

};<o:p></o:p>

<o:p></o:p>

int ACE_TMAIN (int, ACE_TCHAR *[])<o:p></o:p>

{<o:p></o:p>

       ProactorThread thread;<o:p></o:p>

       thread.open();<o:p></o:p>

<o:p></o:p>

       int x;<o:p></o:p>

       std::cin >> x;<o:p></o:p>

<o:p></o:p>

       thread.close();<o:p></o:p>

<o:p></o:p>

       return 0;<o:p></o:p>

}

<o:p></o:p>

仅仅只是添加了一个新的类,用于封装Proactor事件循环线程,另外修改了程序的主函数。这次程序将首先创建一个Proactor事件循环线程,然后主线程等待用户输入任意数后结束Proactor线程,在Proactor线程正常退出后主线程退出。

<o:p></o:p>

注意这里有两个要点:

1.当执行proactor_end_event_loop()之后,Proactor线程是从proactor_run_event_loop()处退出,所以会接着执行下面的代码,打印出” Thread ended”信息。

2.主线程必须使用wait()等待Proactor线程正常结束后再退出,否则如果主线程退出后,Proactor线程仍有一些资源释放工作未完成,那么就会存在资源未正确释放的问题。

 

你可能感兴趣的:(thread,工作,OS)