peakzhang 发表于 2008-9-21 15:37:08

服务器端程序的几个问题

我现在做一个服务器端的程序,也就是对前台的信息进行处理然后再返回结果的很传统功能的那种。采用半同步-半异步模式,即前端和后端采用一个消息队列来传递消息。消息都由一个从 ace_task继承而来的线程池来异步处理,每个线程从消息队列中取得一个消息,然后处理,但我的程序中在线程函数virtual svc ()中含有对另外的对象的调用,而这些对象又在运行时动态申请的内存,正常运行时没有问题,但如果有取消消息到达,则应该把这个线程终止掉,但这样内存得不到释放;
问题1:取消操作是个很平常的问题,ace中一般的处理模式是怎样的?
问题2:用什么方式取消一个线程比较好,比较安全,特别是内存的释放问题?我现在用的是ACE_Thread_Manager::instance()->cancel(cancelingThread,1);函数,也用了直接的kill,都不太好
问题3:怎样使一个线程执行到一半的时候释放内存,然后从svc函数的入口处重新执行?
求斑竹或其他高人指点迷津!

peakzhang 发表于 2008-9-21 15:37:10

对问题1、2,我是发个空消息过去(或者你自己定义一个消息),线程收到后就自己洗洗睡了

3的话,实话说我不太明白你说的意思,不过如果你的线程不是依赖getq()驱动的话,可以将你的事务处理放到一个函数里foo(),由svc()调用。然后foo()可以在最内层的循环里加上条件检查,发现需要重新开始,就处理自己申请了的资源,然后return,回到了svc()自然就是“从svc函数的入口处重新执行”了

peakzhang 发表于 2008-9-21 15:46:43

你的回复对我很有启发。

对问题1、2我是用了一个自定义的消息,但也没你说的那么简单吧,用我现在使用的模式,客户端用户有很多,而且是并发的,所以取消消息必须指定取消的是哪个socket连接上的消息,也就是要取得要取消的句柄,在取消该句柄的所有相关消息。必须做两个工作,1是要干掉在消息队列中有相同句柄号的消息,让他们不被执行,2、干掉线程池中正在运行的相同句柄的线程,因为客户取消是因为系统忙,而系统忙可能是因为运行的线程忙,所以有必要做第2步。   你可能有很多细节没有说,能说得清楚点吗,这个我真的不知道别人是怎么做的!

问题3是我没说清楚。我现在的做法是:线程在运行的时候被取消消息终止了,也就是调用的cancel函数,我有重新开了一个新线程,即调用了active函数,这样是为了保持线程池中的数量不变,生成的新线程的线程号和以前被取消的线程当然是不同的了(说实话,我觉得自己的做法会被别人耻笑),这种机制下出现的问题是被取消的线程的内存得不到释放,所以我想能不能有种机制,线程不cancel掉,能作到在得到取消消息的时候,自己会释放内存,并从svc的入口重新来执行。

非常感谢!

peakzhang 发表于 2008-9-21 15:46:50

我再补充一下:

你说的问题3的解决方式应该是协作式取消把,原则上是可以做的。问题是我们的系统也有一定的复杂性,如果在你上述的foo函数中又涉及到别的对象的生成,对象在运行时又申请新的内存,也就是有多层的情况,内存的释放有保障吗,我想可不可能ace中有一种 类似 auto-ptr这种工具能让系统记录一段代码中申请的动态资源,这样就很好控制了,不用每个细节都要控制

peakzhang 发表于 2008-9-21 15:46:56

1和2的:我是用hash_map 记录各种对应的数值,然后你可以选择prototype模式 或者 factory模式处理
3的话:ace里有auto_ptr

peakzhang 发表于 2008-9-21 15:47:17

非常感谢回复!
我把程序改为了你开始提到的协作式取消,仔细看了ace文档和相关资料后,我发现要实现异步取消问题很多,连《ACE程序员指南》上也申明这种方式处理起来很麻烦,看来这种复杂性是难以避免的,我也忽略了我的代码中的一些细节:在svc()线程中有很多修改外部线程共用的全局变量的代码,如果真的能象我在上面提到的那样用异步取消的方式,那么作到重新恢复这些值将是不可能由ace自动实现的。
总的说来采用协作式取消,其实用的只是检查一个很简单的flag,从而判断是否线程继续执行,但在执行关键的代码块时也是不能频繁检查这个flag的,而这关键的代码块正式系统开销所在;我想要的是那种象unix上CTRL-C终止一个进程那样终止一个线程的效果,因为这样才能让系统尽快的空闲下来,达到真正取消线程的目的。
系统稳定是最重要的!
有谁有好的想法,大家一起谈论把!

[ 本帖最后由 peakzhang 于 2008-9-21 16:08 编辑 ]

peakzhang 发表于 2008-9-21 16:08:45

我接触过的大型系统不多,能算的也只有apache跟kbs这两个,他们共同的做法都是提供一个最大用户(or连接)等参数的设置,然后依靠系统实际运行情况调教。
然后系统只保证在满足这些参数要求的前提下提供尽可能好的用户体验,而不是系统自适应硬件性能,毕竟现在硬件搭配千变万化,要能动态满足所有硬件情况可能会有点得不偿失吧我想。
页: [1]
查看完整版本: 服务器端程序的几个问题