创建一个可正常结束的Proactor服务器
来源:互联网 发布:linux profile 生效 编辑:程序博客网 时间:2024/04/29 05:32
这是APG上关于Proactor使用的例子,去掉了trace信息,做了一点小修改: CODE: 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强大的封装,所做的改动并不大:
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线程仍有一些资源释放工作未完成,那么就会存在资源未正确释放的问题。
- 创建一个可正常结束的Proactor服务器
- 创建一个可正常结束的Proactor服务器
- 创建一个可正常结束的Proactor服务器
- 创建一个可正常结束的Proactor服务器
- 创建一个可正常结束的Proactor服务器
- 创建一个可正常结束的Proactor服务器
- 实现一个可限制最大连接数的Proactor服务器
- 实现一个可限制最大连接数的Proactor服务器
- 实现一个可限制最大连接数的Proactor服务器
- 如何创建一个可配置的产品
- 创建一个可重用的UITableViewCell代码
- Retrofit--创建一个可扩展的客户端
- ACE Proactor模式的一个问题
- Ubuntu创建一个可ssh可sudo的用户
- 一个实验的结束
- 一个软件的结束
- 一个时代的结束
- 《UNIX网络编程》多线程TCP C/S服务器正常启动和正常结束过程剖析
- Linux内核2.6简介
- Understanding the linux kernel 3rd edition
- Linux source code
- struts 中的一些常用方法
- ACE proactor
- 创建一个可正常结束的Proactor服务器
- linux学习笔记5 解决eclipse 之“launch failed. Binary file not found.”
- Linux进程和线程
- VBS中解决路径带空格的三种方法
- 白话数字签名(1)——基本原理(新!)
- 以MD5的方式,sha1 生成散列 加密指定字符串
- 读后感
- FATE hdu 2159 二维的完全背包
- Linux进程状态和变迁