ACE中使用完成端口.

使用ACE中的Proactor的話,會要比我們使用我們直接寫的要來得簡單。
在說Proactor之前我們需要了解Windows裏的完成端口的工作原理。
完成端口是WinNT內核裏的一個框架。我們可以爲我們的一些異步的操作
新建一個完成端口,然後這個完成端口會有幾個工作線程來處理。我們
可以將socket,或是一個文件讀寫,或是一個串口的收發數據的句柄,
梆定到這個完成端口之上,當一個讀或是寫的事件完成之後,完成端口
機制將會自動將一個完成消息放到完成隊列中,完成端口的工作線程池
將會被觸發調用。回調的時候我們梆定時將一些基礎的信息也梆在其中,
當工作線程也會通過一種叫做完成項的指針返回給你。就是說,你可能
梆定了多個socket或是文件都是沒有問題的。按微軟人寫的文檔裏說的
可以面對百萬個這樣的異步對象。
這裏我就不再使用WinAPI寫完成端口了。
現在是使用ACE框架來寫一個。
使用他來做一個完成端口步驟也是一樣的。
開始的時候需要一個完成端口,還有完成端口的工作線程池。在ACE框架
裏提供了一種叫ACE_Task的線程池模塊類
和一般的線程類一樣,它的工作時調用的函數是
virtual int svc (void);
只是如何使用呢。無非是開啓線程與關閉線程兩個操作。
在此類中定義一個ACE_Thread_Semaphore sem_;變量
然後開戶n個線程的過程就是這樣的:
int Proactor_Task::star(int nMax)
{
 ...
 this->activate (THR_NEW_LWP, nMax);
 for (;nMax>0;nMax--)
 {
  sem_.acquire();
 }
 return 0;
}
一個是創建,二個是一個一個的觸發。讓這一些線程都工作.
當然工作線程都要釋放自己:

int Proactor_Task::svc()
{
 ACE_DEBUG((LM_INFO,ACE_TEXT("svc函數調用!/n")));
 sem_.release(1);
 ...
 return 0;
}

好了。這個線程池開始工作了。接下來,我們要做將完成端口對象給創建出來:
在這個線程池裏定義一個完成端口對象指針:
ACE_Proactor * proactor_;
創建的過程是這樣的。
//是在Win32下,就使用這個Proactor的實現
ACE_WIN32_Proactor *proactor_impl = new ACE_WIN32_Proactor();   //新建proactor的實現
proactor_=new ACE_Proactor(proactor_impl,1);     //與proactor關聯
ACE_Proactor::instance (this->proactor_, 1);     //將新建出來的proactor保存在靜態框架裏

如何刪除呢。
ACE_Proactor::end_event_loop();
this->wait();

之後來寫線程池裏的函數
 ACE_Proactor::run_event_loop();
只要寫一句就OK了。

這就完成了一個完成端口對象的創建過程。我們只要做一下封裝就OK了。
給它一個工作線程的大小。之後它就會自動的新建一個完成端口在ACE_Proactor::instance裏。

接下來我們要做Acceptor與recv。
實計上ACE裏已經爲我們寫好了。它們就是:
ACE_Asynch_Acceptor類ACE_Service_Handler類
class Accepte : public ACE_Asynch_Acceptor<Receive>
class Receive : public ACE_Service_Handler
這樣一繼承,工作就已經完成了。
如果我們想得到這一些網絡事件的話,可以做一些繼承就OK了。
他們內部調用的過程是這樣的:
當有一個新的用戶連接上來之後。
Accepte會有一個函數回調。
virtual HANDLER *make_handler (void);
這個函數裏,我們必需寫一個new Receive對象。
new完成之後Receive的open函數將會回調
open函數調用的時候,此接收對象的socket句柄就得到了。我們就在這個時候需要將一個
讀、寫的流梆定在其中。還有就是做一步異步的接收數據。這個如果你寫過重疊方式的話就會
比較的瞭解,這也叫做異步的I/O的投遞。等這個recv完成之後就會回調。
好了。這就算完成了。現在把代碼貼出來。
我不知道如何做一個下載點。不好意思只有大家自己複製下來
我使用的VC6.0,ACE5.4.1的編程環境

// Accepte.h: interface for the Accepte class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_ACCEPTE_H__DCEC809D_E5D2_48D1_A8A7_C9FD3C4D7C15__INCLUDED_)
#define AFX_ACCEPTE_H__DCEC809D_E5D2_48D1_A8A7_C9FD3C4D7C15__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <ace/Asynch_Acceptor.h>
#include "Receive.h"
class Accepte : public ACE_Asynch_Acceptor<Receive>
{
public:
 Receive* make_handler (void);
 Accepte();
 virtual ~Accepte();

};

#endif // !defined(AFX_ACCEPTE_H__DCEC809D_E5D2_48D1_A8A7_C9FD3C4D7C15__INCLUDED_)


// Accepte.cpp: implementation of the Accepte class.
//
//////////////////////////////////////////////////////////////////////

#include "Accepte.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Accepte::Accepte()
{

}

Accepte::~Accepte()
{

}

Receive* Accepte::make_handler(void)
{
 return new Receive();
}

// Proactor_Task.h: interface for the Proactor_Task class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_PROACTOR_TASK_H__12F37C95_9872_4923_89A2_5A59AE7AC1FD__INCLUDED_)
#define AFX_PROACTOR_TASK_H__12F37C95_9872_4923_89A2_5A59AE7AC1FD__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include "ace/Task_T.h"
#include "ace/Thread_Semaphore.h"

#include "ace/Proactor.h"
#include "ace/WIN32_Proactor.h"
class Proactor_Task : public ACE_Task<ACE_MT_SYNCH>
{
public:
 Proactor_Task();
 virtual ~Proactor_Task();
 int star(int nMax);
 int stop();
 virtual int svc (void);
 int create_proactor();
 int release_proactor();
 ACE_Thread_Semaphore sem_;
 ACE_Proactor * proactor_;
};

#endif // !defined(AFX_PROACTOR_TASK_H__12F37C95_9872_4923_89A2_5A59AE7AC1FD__INCLUDED_)


// Proactor_Task.cpp: implementation of the Proactor_Task class.
//
//////////////////////////////////////////////////////////////////////

#include "Proactor_Task.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Proactor_Task::Proactor_Task()
{

}

Proactor_Task::~Proactor_Task()
{

}

int Proactor_Task::star(int nMax)
{
 create_proactor();
 this->activate (THR_NEW_LWP, nMax);
 for (;nMax>0;nMax--)
 {
  sem_.acquire();
 }
 return 0;
}

int Proactor_Task::stop()
{
 ACE_Proactor::end_event_loop();
 this->wait();
 return 0;
}

int Proactor_Task::release_proactor()
{
 ACE_Proactor::close_singleton ();
 proactor_ = 0;
 return 0;
}
int Proactor_Task::create_proactor()
{
 ACE_WIN32_Proactor *proactor_impl = 0;
 
 ACE_NEW_RETURN (proactor_impl,
  ACE_WIN32_Proactor,
  -1);
  // always delete implementation  1 , not  !(proactor_impl == 0)
 ACE_NEW_RETURN (this->proactor_,
  ACE_Proactor (proactor_impl, 1 ),
  -1);
 // Set new singleton and delete it in close_singleton()
 ACE_Proactor::instance (this->proactor_, 1);

 return 0;
}

int Proactor_Task::svc()
{
 ACE_DEBUG((LM_INFO,ACE_TEXT("svc函數調用!/n")));
 sem_.release(1);
 ACE_Proactor::run_event_loop();
 return 0;
}

// Receive.h: interface for the Receive class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_RECEIVE_H__0E7EF8C0_465F_4D9C_8A29_0C2A0F1EAFFE__INCLUDED_)
#define AFX_RECEIVE_H__0E7EF8C0_465F_4D9C_8A29_0C2A0F1EAFFE__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000
#include <ace/Asynch_io.h>
#include <ace/Message_Block.h>
#include <ace/Log_Msg.h>
#include <ace/OS_Memory.h>
class Receive : public ACE_Service_Handler
{
public:
 Receive();
 virtual ~Receive()
 {
  if (this->handle() != ACE_INVALID_HANDLE )
  {
   closesocket(SOCKET(this->handle()));
  }
 }
 virtual void open(ACE_HANDLE h,ACE_Message_Block& );
 virtual void handle_read_stream(const ACE_Asynch_Read_Stream::Result &result);
 virtual void handle_write_stream(const ACE_Asynch_Write_Stream::Result &result);
private:
 ACE_Asynch_Write_Stream write_;
 ACE_Asynch_Read_Stream reader_;

};

#endif // !defined(AFX_RECEIVE_H__0E7EF8C0_465F_4D9C_8A29_0C2A0F1EAFFE__INCLUDED_)

// Receive.cpp: implementation of the Receive class.
//
//////////////////////////////////////////////////////////////////////

#include "Receive.h"

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

Receive::Receive()
{

}
void Receive::open(ACE_HANDLE h,ACE_Message_Block& )
{
 this->handle(h);
 if (this->write_.open(*this)!=0 ||
  this->reader_.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)
 {
  ACE_ERROR((LM_ERROR,ACE_TEXT(" (%t) error information %p.")));
  mb->release();
  delete this;
  return;
 }
}
void Receive::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_Message_Block* new_mb;
  ACE_NEW_NORETURN(new_mb,ACE_Message_Block(1024));
  this->reader_.read(*new_mb,new_mb->space());
 }
 return ;
}

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

////////////////////////////////////////////////////////////////////////////////////////////////////
//main.cpp

#ifdef _DEBUG
 #pragma comment(lib,"aced")
#else
 #pragma comment(lib,"ace")
#endif
#include <ace/ace.h>
#include "Accepte.h"
#include "Proactor_Task.h"

int ACE_TMAIN(int ,char*[])
{
 Proactor_Task task;
 task.star(3);
 
 Accepte accepte;
 accepte.open(ACE_INET_Addr (2222), 0, 1,ACE_DEFAULT_BACKLOG,1,ACE_Proactor::instance());
 int nExit=0;
 while (nExit==0)
  scanf("%d",&nExit);
 return 0;
}

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章