ACE源代码目录结构
ACE(ADAPTIVE Communication Environment),中文的意思就是自適配通訊環境,ACE是一個用于開發網絡程序的優秀的C++的框架,在國外有很廣泛的使用,在國內一些大的開發通訊產品的公司也有使用。我接觸ACE也有一段時間了,雖然時間不長,但我還是感覺到ACE確實是一個好東西,對于豐富自己的知識面有很大的幫助。雖然我們項目目前是采用C語言來開發,但是當接觸ACE后,你會發現“喔,原來程序還可以這樣”。例如:我覺得ACE里面Reactor框架就是一個非常的東西,我們在開發網絡程序的時候,常常采用poll來監視各種網絡事件,但當采用該框架后,你現在只是需要關系你的業務邏輯,當發生特定的網絡事件后,框架會回調你的業務邏輯。其實按照這個思路,我們完全可以用C來實現類似的功能,當你完成這個后,你會發現你原來用C語言寫的過程風格的代碼竟然有了OO的味道。
ACE確實是好東西,但也不是能輕松的就能掌握的,我們還需要一步一步的來蠶食這個大象。
萬丈高樓平地起,首先我們還是了解一下ACE的目錄結構,從整體上對ACE有一個認識,為今后的進一步學習打下一個基礎。
解開ACE的壓縮包后,你會發現一個ACE_wrappers目錄,這個目錄也就是ACE的HOME目錄,它下面還包含著一些子目錄:
ace:這個目錄是ACE中最重要的目錄,它包含了ACE的所有源碼,但遺憾的是,ACE的所有源文件和頭文件全部雜亂的堆在這個目錄里,這可能也是很多開源軟件的缺點。其實ACE的代碼完全可以按照不同的功能進行不同目錄的劃分,例如:Reactor框架和thread框架代碼完全可以劃分開,我想一個代碼組織良好的ACE,將會給大家的學習帶來極大的好處,我將在后面的文章里給出ACE代碼劃分的方法;
ACEXML:這個目錄包含了用ACE實現的一個XML解析器;
apps:這個目錄包含了用ACE來實現的一些較大的應用程序,例如:JAWS,一個WEB服務器;
ASNMP:基于ACE的SNMP協議實現;
bin:包含里用例方便開發的perl腳本程序,例如:在WIN32上開發DLL時候,需要導出DLL的接口;
docs:ACE的一些幫助文檔,其中ACE-subsets.html文檔,對我們劃分ACE的代碼有很大的幫助;
examples:是用ACE來編寫的一些例子程序,方便更好的學習和理解ACE;
include:也是ACE中一個比較重要的目錄,它包含了在不同的平臺上編譯時候的編譯規則,庫的編譯規則等;
netsvcs:一些基于ACE的在分布式系統中常用的程序,例如:分布式系統日志系統,網絡鎖,時間同步等;
TAO:基于ACE的實時CORBA實現,TAO在分布式系統中使用相當廣泛,也是一個不可多得的好資源;
tests:用來對ACE進行回歸測試,也提供了一個學習ACE的很好的例子代碼;
***********************************************************************************************************************************
?
前幾篇文章也提到過,ACE的所有源文件和頭文件都雜亂堆在了ACE_wrappers/ace目錄下。這樣的代碼組織方式給學習ACE帶來了很大的困難,很多朋友在看到ace目錄下龐大的代碼的時候,幾乎就失去了學習ACE的信心^_^。因此,我們有必要對ACE的代碼進行重新組織,以降低學習曲線。下面,我將給出我對ACE源碼的劃分方法。其實,我也是剛學習ACE沒有多久,對ACE的了解還甚少,所以,我的源碼劃方式法不一定十分正確,這里共享出來,僅供大家參考。
其實,在ACE的幫助文檔里,ACE-subsets.html和ACE-categories.html,這兩個文檔對指導ACE的源碼劃分起到了很大的作用,否則,我剛剛接觸ACE,就想對其進行源碼劃分,是不可能完成的。ACE-subsets.html,這個文檔主要介紹了ACE的library subsetting。正常情況下,在編譯完ACE后,只會產生一個ACE的庫。我們可以根據該文檔的介紹,簡單的修改一下Makefile,就可以對ACE的庫進行子集化,我們可以編譯出OS、Thread等這樣的子庫。ACE-categories.html,這個文檔對ACE中的代碼進行了一些功能上的分類。具體大家可以詳細的參考一下這兩個文檔,這兩個文檔對學習ACE還是有一定的幫助的。
在ACE的源代碼目錄ace下,我將建立很多子目錄,來對ACE的代碼進行按功能分類:
ACE_OS:該目錄里包含的代碼是OS的API的wrapper,也就是ACE的OS適配層;
包含代碼: ARGV.cpp????????? OS_Memory.cpp
?? Argv_Type_Converter.cpp???? OS_QoS.cpp
?? Base_Thread_Adapter.cpp???? OS_String.cpp
?? Basic_Types.cpp???????????? OS_TLI.cpp
?? Copy_Disabled.cpp?????????? OS_Thread_Adapter.cpp
?? Env_Value_T.cpp???????????? Sched_Params.cpp
?? Handle_Set.cpp???????? Template_Instantiations.cpp
?? Makefile??????????????????? Thread_Hook.cpp
?? OS.cpp????????????????????? Time_Value.cpp
?? OS_Dirent.cpp????????????????
?? OS_Errno.cpp?????????????????
?? OS_Log_Msg_Attributes.cpp
ACE_Codec:該目錄包含的是ACE的各種編碼類型的處理代碼,目前只包含了BASE64編碼的處理;
??? 包含代碼:Codecs.cpp??? Makefile
ACE_Connection:該目錄包含的是ACE中的Acceptor-Connector框架代碼和異步通訊類代碼;
?? 包含代碼:Acceptor.cpp??????????? Connector.cpp
??? Asynch_Acceptor.cpp???????????? Makefile
??? Asynch_Connector.cpp???????? POSIX_Asynch_IO.cpp
??? Asynch_IO.cpp?????????????????? Strategies_T.cpp
??? Asynch_IO_Impl.cpp????????????? Svc_Handler.cpp
??? Asynch_Pseudo_Task.cpp?????? WIN32_Asynch_IO.cpp
??? Cached_Connect_Strategy_T.cpp??
??? Caching_Strategies_T.cpp???????
ACE_Demux:該目錄包含的是ACE中的Reactor和Proactor框架代碼;
??? 包含代碼:Dev_Poll_Reactor.cpp????? Priority_Reactor.cpp????? TP_Reactor.cpp??????? Event_Handler.cpp???????? Proactor.cpp????????????? TkReactor.cpp
?? Event_Handler_T.cpp?????? QtReactor.cpp???????????? WFMO_Reactor.cpp
?? FlReactor.cpp???????????? Reactor.cpp?????????????? WIN32_Proactor.cpp
?? Makefile????????????????? SUN_Proactor.cpp????????? XtReactor.cpp
?? Msg_WFMO_Reactor.cpp????? Select_Reactor.cpp???????
?? POSIX_CB_Proactor.cpp???? Select_Reactor_Base.cpp??
?? POSIX_Proactor.cpp??????? Select_Reactor_T.cpp
ACE_IPC:該目錄包含的是ACE中進程間通訊的一些封裝代碼:
包含代碼:ATM_Acceptor.cpp???????????? Makefile
?? ATM_Addr.cpp???????????????? Pipe.cpp
?? ATM_Connector.cpp??????????? SPIPE.cpp
?? ATM_Params.cpp?????????????? SPIPE_Acceptor.cpp
?? ATM_QoS.cpp????????????????? SPIPE_Addr.cpp
?? ATM_Stream.cpp?????????????? SPIPE_Connector.cpp
?? DEV.cpp????????????????????? SPIPE_Stream.cpp
?? DEV_Addr.cpp???????????????? SV_Message.cpp
?? DEV_Connector.cpp??????????? SV_Message_Queue.cpp
?? DEV_IO.cpp?????????????????? SV_Semaphore_Complex.cpp
?? FIFO.cpp???????????????????? SV_Semaphore_Simple.cpp
?? FIFO_Recv.cpp??????????????? SV_Shared_Memory.cpp
?? FIFO_Recv_Msg.cpp??????????? Signal.cpp
?? FIFO_Send.cpp??????????????? TLI.cpp
?? FIFO_Send_Msg.cpp??????????? TLI_Acceptor.cpp
?? FILE.cpp???????????????????? TLI_Connector.cpp
?? FILE_Addr.cpp??????????????? TLI_Stream.cpp
?? FILE_Connector.cpp?????????? TTY_IO.cpp
?? FILE_IO.cpp????????????????? Typed_SV_Message.cpp
?? IOStream.cpp???????????????? Typed_SV_Message_Queue.cpp
?? IOStream_T.cpp?????????????? UNIX_Addr.cpp
?? IO_SAP.cpp?????????????????? UPIPE_Acceptor.cpp
?? MEM_Acceptor.cpp???????????? UPIPE_Connector.cpp
?? MEM_Addr.cpp???????????????? UPIPE_Stream.cpp
?? MEM_Connector.cpp??????????? XTI_ATM_Mcast.cpp
?? MEM_IO.cpp??????????????????
?? MEM_SAP.cpp?????????????????
?? MEM_Stream.cpp
ACE_LIB:該目錄將包含ACE編譯好的各個子庫;
ACE_Logging:該目錄包含ACE中的日志處理相關代碼;
?????? 包含代碼:Dump.cpp?????????????????? Log_Msg_UNIX_Syslog.cpp
?? Dump_T.cpp???????????????? Log_Record.cpp
?? Log_Msg.cpp??????????????? Logging_Strategy.cpp
?? Log_Msg_Backend.cpp??????? Makefile
?? Log_Msg_Callback.cpp?????? Trace.cpp
?? Log_Msg_IPC.cpp???????????
?? Log_Msg_NT_Event_Log.cpp??
ACE_Memory:該目錄包含了ACE內存處理相關代碼;
???? 包含代碼:Based_Pointer_Repository.cpp?? Obstack.cpp
?? Based_Pointer_T.cpp??????????? Obstack_T.cpp
?? Makefile?????????????????????? PI_Malloc.cpp
?? Malloc.cpp???????????????????? Read_Buffer.cpp
?? Malloc_Allocator.cpp?????????? Shared_Memory.cpp
?? Malloc_Instantiations.cpp????? Shared_Memory_MM.cpp
?? Malloc_T.cpp?????????????????? Shared_Memory_SV.cpp
?? Mem_Map.cpp???????????????????
?? Memory_Pool.cpp???????????????
?? Obchunk.cpp
ACE_Misc:ACE中一些沒有明確功能分類的代碼,屬于雜項;
?? 包含代碼:CE_Screen_Output.cpp?? NT_Service.cpp
?? Makefile?????????????? gethrtime.cpp
ACE_Nameservices:該目錄包含了ACE中名字服務相關代碼;
??? 包含代碼: Name_Space.cpp
??? Local_Name_Space.cpp?????????? Naming_Context.cpp
??? Local_Name_Space_T.cpp???????? Registry_Name_Space.cpp
??? Makefile?????????????????????? Remote_Name_Space.cpp
??? Name_Proxy.cpp????????????????
??? Name_Request_Reply.cpp????????
ACE_Sockets:該目錄包含的是ACE的socket封裝代碼;
????? 包含代碼:Addr.cpp?????????????????????? SOCK_CODgram.cpp
?? INET_Addr.cpp????????????????? SOCK_Connector.cpp
?? IPC_SAP.cpp??????????????????? SOCK_Dgram.cpp
?? LOCK_SOCK_Acceptor.cpp???????? SOCK_Dgram_Bcast.cpp
?? LSOCK.cpp????????????????????? SOCK_Dgram_Mcast.cpp
?? LSOCK_Acceptor.cpp???????????? SOCK_IO.cpp
?? LSOCK_CODgram.cpp????????????? SOCK_SEQPACK_Acceptor.cpp
?? LSOCK_Connector.cpp??????????? SOCK_SEQPACK_Association.cpp
?? LSOCK_Dgram.cpp??????????????? SOCK_SEQPACK_Connector.cpp
?? LSOCK_Stream.cpp?????????????? SOCK_Stream.cpp
?? Makefile?????????????????????? Sock_Connect.cpp
?? Multihomed_INET_Addr.cpp??????
?? SOCK.cpp??????????????????????
?? SOCK_Acceptor.cpp
ACE_Streams:該目錄包含了ACE中的Streams和Task框架代碼;
????? 包含代碼:CDR_Base.cpp??????????????????????? Module.cpp
?? CDR_Stream.cpp????????????????????? Multiplexor.cpp
?? Codeset_IBM1047.cpp???????????????? Reactor_Notification_Strategy.cpp
?? Codeset_Registry.cpp??????????????? Stream.cpp
?? Codeset_Registry_db.cpp???????????? Stream_Modules.cpp
?? IO_Cntl_Msg.cpp???????????????????? Task.cpp
?? Makefile??????????????????????????? Task_T.cpp
?? Message_Queue.cpp??????????????????
?? Message_Queue_T.cpp???
ACE_Svcconf:該目錄包含了ACE中的Service Configurator框架代碼;
????? 包含代碼:DLL.cpp??????????????????? Service_Types.cpp
?? DLL_Manager.cpp??????????? Shared_Object.cpp
?? Dynamic_Service.cpp??????? Svc_Conf.l
?? Dynamic_Service_Base.cpp?? Svc_Conf.y
?? Makefile?????????????????? Svc_Conf_Lexer_Guard.cpp
?? Parse_Node.cpp???????????? Svc_Conf_l.cpp
?? Service_Config.cpp???????? Svc_Conf_y.cpp
?? Service_Manager.cpp??????? XML_Svc_Conf.cpp
?? Service_Object.cpp????????
?? Service_Repository.cpp????
?? Service_Templates.cpp
ACE_Threads:該目錄包含了ACE中的線程和同步機制相關代碼,例如:thread manager;
????? 包含代碼:Activation_Queue.cpp????? Process_Manager.cpp?????? Thread.cpp
?? Atomic_Op.cpp???????????? Process_Mutex.cpp???????? Thread_Adapter.cpp
?? Atomic_Op_T.cpp?????????? Process_Semaphore.cpp???? Thread_Control.cpp
?? File_Lock.cpp???????????? RW_Process_Mutex.cpp????? Thread_Exit.cpp
?? Future.cpp??????????????? Synch.cpp???????????????? Thread_Manager.cpp
?? Future_Set.cpp??????????? Synch_Options.cpp???????? Token.cpp
?? Makefile????????????????? Synch_T.cpp??????????????
?? Process.cpp?????????????? Test_and_Set.cpp?????????
ACE_Timer:該目錄包含ACE中和時間相關的代碼;
???? 包含代碼:Timer_Heap.cpp
?? Basic_Stats.cpp??????????? Timer_Heap_T.cpp
?? High_Res_Timer.cpp???????? Timer_List.cpp
?? Makefile?????????????????? Timer_List_T.cpp
?? Profile_Timer.cpp????????? Timer_Queue.cpp
?? System_Time.cpp??????????? Timer_Queue_Adapters.cpp
?? Time_Request_Reply.cpp???? Timer_Queue_T.cpp
?? Timeprobe.cpp????????????? Timer_Wheel.cpp
?? Timeprobe_T.cpp??????????? Timer_Wheel_T.cpp
?? Timer_Hash.cpp????????????
?? Timer_Hash_T.cpp??????????
ACE_Token:Token是ACE中實現的一種同步機制,保證嚴格的FIFO或LIFO策略來獲得鎖。ACE通過Token機制實現了分布式同步機制。
???? 包含代碼:Local_Tokens.cpp????????? Token_Collection.cpp????? Token_Request_Reply.cpp
?? Makefile????????????????? Token_Invariants.cpp?????
?? Remote_Tokens.cpp???????? Token_Manager.cpp????????
ACE_Utils:ACE中的一些基礎數據結構和算法的工具類代碼;
??? 包含代碼:ACE.cpp???????????????????????????? Init_ACE.cpp
?? Active_Map_Manager.cpp????????????? Intrusive_List.cpp
?? Active_Map_Manager_T.cpp??????????? Intrusive_List_Node.cpp
?? Arg_Shifter.cpp???????????????????? Lib_Find.cpp
?? Array_Base.cpp????????????????????? Makefile
?? Auto_IncDec_T.cpp?????????????????? Managed_Object.cpp
?? Auto_Ptr.cpp??????????????????????? Map.cpp
?? Cache_Map_Manager_T.cpp???????????? Map_Manager.cpp
?? Caching_Utility_T.cpp?????????????? Map_T.cpp
?? Capabilities.cpp??????????????????? Message_Block.cpp
?? Cleanup_Strategies_T.cpp??????????? Message_Block_T.cpp
?? Configuration.cpp?????????????????? Method_Request.cpp
?? Configuration_Import_Export.cpp???? Node.cpp
?? Connection_Recycling_Strategy.cpp?? Notification_Strategy.cpp
?? Containers.cpp????????????????????? Object_Manager.cpp
?? Containers_T.cpp??????????????????? Pair.cpp
?? Date_Time.cpp?????????????????????? Pair_T.cpp
?? Dirent.cpp????????????????????????? RB_Tree.cpp
?? Dirent_Selector.cpp???????????????? Recyclable.cpp
?? Dynamic.cpp???????????????????????? Refcountable.cpp
?? Filecache.cpp?????????????????????? Registry.cpp
?? Flag_Manip.cpp????????????????????? SString.cpp
?? Framework_Component.cpp???????????? Sample_History.cpp
?? Framework_Component_T.cpp?????????? Singleton.cpp
?? Free_List.cpp?????????????????????? Stats.cpp
?? Functor.cpp???????????????????????? String_Base.cpp
?? Functor_T.cpp?????????????????????? String_Base_Const.cpp
?? Get_Opt.cpp???????????????????????? Swap.cpp
?? Handle_Ops.cpp????????????????????? Unbounded_Queue.cpp
?? Hash_Cache_Map_Manager_T.cpp??????? Unbounded_Set.cpp
?? Hash_Map_Manager.cpp??????????????? Unbounded_Set_Ex.cpp
?? Hash_Map_Manager_T.cpp????????????? Vector_T.cpp
?? Hash_Map_With_Allocator_T.cpp??????
?? Hashable.cpp???????????????????????
include:該目錄又包含子目錄ace,也就是說include/ace/目錄下,包含了ACE的所有頭文件和.i文件,之所以這樣組織,是因為ACE中的源 文件和頭文件的包含文件的方式為:#include "ace/OS.h",所以采用這種目錄結構方式來存放頭文件和.i文件。這里,對頭文件和.i?? 文件,沒有進一步按照功能劃分,就是因為#include "ace/OS.h"這種包含方式,如果頭文件和.i文件也按照功能劃分,那么代碼修改 量相當大;
????????????
通過上面給出的目錄結構和源文件功能劃分及頭文件組織方式,相信讀者以可以自行對ACE代碼進行整理了。在實際整理和編譯代碼的過程中,需要修改Makefile和ACE頭文件中以_T方式為后綴的頭文件,例如:Obstack_T.h,需要修改里面模板源文件包含路徑。我將在下一篇文章中進行描述。
我再次強調,上面ACE源碼劃分方式,不一定十分正確^_^,隨著我們ACE學習和理解的深入,我們可能會進行更改。其實,在我們整理ACE源文件的時候,我們可以進一步了解ACE的各個源文件大致功能,對我們以后更深入的學習大有裨益。
?
***********************************************************************************************************************************
在ACE的源代碼目錄里,有源文件.cpp、頭文件.h,我們還發現有以.i和.inl為擴展名的文件。其實,以.i和.inl為擴展名的文件是ACE源碼中inline函數的存放形式。
在說明ACE中為什么采用這種方式來存放inline函數之前,我們來說一下inline關鍵字是什么意識。我們知道當調用一個函數的時候,涉及到返回地址和參數壓棧等一些操作,這些操作是函數調用本身的開銷。在原來的C代碼中,通常采用宏定義的方式模擬函數,來消除函數調用的開銷,因此我們知道宏是在預編譯時候進行處理的。但是,宏定義本身也有很多缺陷,很容易造成錯誤的使用。這就是inline關鍵字誕生的原因。用inline關鍵字定義的函數,在編譯的時候,并不會產生真正的函數,而是在該函數調用處直接展開代碼,這樣就消除了函數調用的開銷。注意,inline關鍵字,只是給編譯器的一個暗示,是不是真的進行了inline處理,是由編譯器決定的。
那為什么ACE會采用這樣一個特殊的方式來存放inline函呢?我們結合實例給出答案。
我們看一下,Reactor.h文件的結尾處,有如下的處理:
#if defined (__ACE_INLINE__)
#include "ace/Reactor.i"
#endif /* __ACE_INLINE__ */
在看一下Reactor.cpp文件開頭處的宏處理:
#if !defined (__ACE_INLINE__)
#include "ace/Reactor.i"
#endif /* __ACE_INLINE__ */
上面的Reactor.h,Reactor.cpp和Reactor.i文件是ACE的Reactor框架的相關代碼。上面的宏定義我們很好理解,在頭文件中的處理為:如果定義了宏__ACE_INLINE__,那么我們就把Reactor.i文件include到頭文件中。在源文件中處理為:如果沒有定義宏__ACE_INLINE__,那么就把Reactor.i文件include到源文件中。其實有了上面inline含義的介紹,我們不難理解為什么采用這種方式來進行處理。這里我們假設定義了宏__ACE_INLINE__,并且Reactor.i文件是被include到源文件里,而不是被include頭文件里,那么會產生什么后果那?我們知道inline函數,在編譯器編譯后,是不會產生真正的函數的,因此,如果有其它源文件,例如zhx.cpp,調用了Reactor.i文件中的inline函數,那么在連接的時候,就會拋出符號無法解析的錯誤,而如果Reactor.i文件是被include到了頭文件中,并且我們在zhx.cpp中有調用Reactor.i文件中的函數,那么在zhx.cpp中,只需要包含Reactor.h頭文件即可,則Reactor.i的相關inline函數在zhx.cpp也進行了代碼展開處理。如果沒有定義宏__ACE_INLINE__,則Reactor.i被include到源文件中,沒有任何問題,因為Reactor.i中的函數在編譯后,會產生真正的函數,而不是被inline處理。這就是ACE為什么采用這樣的方式進行處理的原因。
在上面的介紹中,我們同時也發現了inline的缺點,就是它會造成代碼的膨脹。因此,不是什么樣的函數都適合用inline來定義,只有那些短小的函數才適合采用inline處理。
注:ACE為什么會采用.i和.inl兩種擴展名形式的文件來存放inline函數,我還不是很清楚,但感覺以.inl形式存放的文件是早期ACE代碼中的方式,后期的ACE代碼采用.i方式來存放inline函數,也就是說這應該是一個歷史遺留問題^_^,開源項目的缺點。
總結
以上是生活随笔為你收集整理的ACE源代码目录结构的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 使用 ACE 库框架在 UNIX 中开发
- 下一篇: ACE入门---很好的文章