1、多线程中的ACE_Reactor::EventLoop,当在多线程(池)中调用EventLoop时,需要注意,在Acceptor/EventHandler中要使用其中的方法Reactor()来获取ACE_Reactor的指针,不要使用ACE_Reactor::instance,道理很简单哟。不过,一定要注意,在编程时,使用Reactor()类方法,比使用单件的方法要好很多,起码安全,也不会破坏封装性。
2、ACE_Task中的Msg_Queue,这个类的确很迷人,不过要注意getq和putq都可能会引起阻塞,因此,最好使用超时的方式来调用它们,特别是在结束这个task时候。因为,你要清空msg_queue,如果不超时,你可能无法安全的退出线程。
3、ACE_Svc_Handler,这个类很好,它继承于ACE_Task,因此它有msg_queue,还可以被用于ACE的组件配置模型中。其中对于handle_output,要注意,因为它不会自动被框架调用,除非你使用了策略类ACE_Reactor_Notification_Strategy(msg_queue需要它,windows下用的是完成端口),它使用流控制方式通知你可以写。而且,在handle_output内,不要吝惜,一定要使用while,把msg_queue里面的message_block尽可能全部取出,然后发送出去(直到send返回-1,errono=EWOULDBLOCK)。
4、Acceptor/Handler,要在end_event_loop之前被清除。如果使用了new创建acceptor的话,最好在end_event_Loop前,注销它,即在handle_close时用参数DONT_CALL注销,并delete。如果你是在end_event_loop 后在删除它的话,ACE保证会让你遇到无法让你冷静的崩溃断言等致命错误 。有一种思想,就是如果new出来的对象指针,在程序退出前,一直没有变化,也就是说,对象依然被你掌控的话,你可以不用去delete,而且,这个也不叫内存泄露。因为现在的操作系统,在进程被杀死后,会清理进程使用过的空间。
5、善使局部类(在函数体中声明定义的类),严格意义上讲,这个不是ace范畴。局部类对象,可以共享全局/静态的数据,但是不能直接使用函数体内的数据;或者成员函数所在类内的变量,不过可以使用所在类指针,访问类的私用成员。这个很强悍,可以做一些很私密的处理。而且,可以利用这一点,返回一个局部类对象指针(当然是void*),而c++保证,外界无法访问访问它,更不能删除它。
6、EMSGSIZE,这个errorcode,我当初没有理解,只是在实践中碰到了,当你请求的数据length,小于实际数据长度时,会有这个error。这时,我们可以采取约定的方式,即,我们每次不得发送数据长度超过MTU的包,接收当然也不会超过这个数值。也不会报这个error。而且这样做有好处,起码可以防止别人恶意发送长度很大的包来攻击你。而且,更重要的是,小于MTU的数据不会被分包传输,数据安全而且可靠。这点对tcp/udp同样适用哟。
7、ace用于mfc环境,或者说用于共享库(dll、so等)时,最好在使用前使用ACE::init初始化一下,并在退出前使用ACE::fini。