找回密码
 用户注册

QQ登录

只需一步,快速开始

查看: 9534|回复: 13

proactor windows下的线程模型问题

[复制链接]
发表于 2007-12-18 23:55:59 | 显示全部楼层 |阅读模式
windows下实现是用i/o完成端口的,
我的问题是投递的多个异步读写(对同一个文件句柄)是否有可能被
系统同时执行?因为看到的资料都说i/o完成端口可以有多个线程同时
执行异步读写的。
如果可能被同时执行的话,那么操作系统(i/o完成端口)能保证同步吗?
 楼主| 发表于 2007-12-18 23:56:02 | 显示全部楼层
当然可以,不过最好是在读完之前不要投递下一个读,在写完成之前不要投递下一个写,呵呵
发表于 2007-12-19 10:11:20 | 显示全部楼层
这个问题我也研究了很久
在多线程模式下使用proactor的主要做法就是在多个线程中调用Proactor的handle_event
而handle_event会阻塞在等待系统消息,如果是完成端口的话就是GetQueuedCompletionStatus这个函数
这样当有事件到达的时候GetQueuedCompletionStatus就会从阻塞状态返回,handle_event就可以继续完成
消息分派,从而回调对应事件的完成处理.从上面的分析可知道如果多线程调用GetQueuedCompletionStatus
当同时到达多个事件时就会发生并发处理,理论上所有的事件都是可能并发的,同一个事件的处理函数也是可
能重入的(多个线程同时执行同一个回调)
发表于 2007-12-19 10:17:58 | 显示全部楼层
确实如此。你说的没错。使用proactor的主要做法就是在多个线程中调用Proactor的处理循环。
一定要注意的是,处理器对象的各个虚方法,都是可能被多线程处理的,如果不注意,很可能导致处理错误。
发表于 2007-12-19 10:25:23 | 显示全部楼层
最近在做一个proxy需要将两个端口关联起来,比如A-B两个端口关联起来建立了一个channel,由于A和B之间需要互相调用Send,所以他们需要相互了解(相互拥有对方的指针或者句柄)那么当A关闭的时候应该通知B关闭,这样在资源释放上处理很困难,特别是在多线程的异步环境下,版主有没有什么好的建议啊:):) :)
发表于 2007-12-19 10:37:15 | 显示全部楼层
我遇见过你说的情况,就是A-B之间需要接口相互使用。有几种办法可以处理的,仅供参考,如果你有更好的办法,请回帖告诉我。
1、参考ACE里面的智能指针,有强弱之分,能够在指针对象析构的时候自动改变状态。
2、使用引用计数,把A / B保护起来,注意得防止A / B正在执行的时候,被另外的线程处理删除,导致崩溃,这个问题几率很低,所以很多人意识不到,出了问题又很难想到和查到。
3、A和B都是单件,永不清除,只有状态变化的差别,比如是否能发送、收取等。
发表于 2007-12-19 10:45:16 | 显示全部楼层
智能指针是个不错的选择,但是智能指针是针对内存资源的,那么如果io资源出现并发,比如在A端口上发起了写之前,另一个线程关闭了A端口,会出现什么现象了?我用loadrunner测试用proactor写的echoserver,如果server不主动调用closesocket那么并发100个用户可以很稳定的跑起来,但是如果加上了closesocket,并发100个连接的时候,loadrunner就会在connect的时候超时退出.
发表于 2007-12-19 10:48:37 | 显示全部楼层
在JAWS2中,资源的释放是和一次处理请求绑定在一起的,从一个端口接受了一个http请求包放在JAWS_Message_Block类的对象中,这个对象贯穿了一次完整处理周期,只有当一次完整处理结束了,这个对象才会被释放,这个对象的释放也会触发端口资源的释放
发表于 2007-12-19 10:53:51 | 显示全部楼层
嗯。具体问题具体分析。
A / B在相互引用的情况下,非常容易出现“环”,出现环状调用很可能导致死锁发生。这时可以用设计模式的一些技巧,把环解开。
发表于 2007-12-19 11:07:23 | 显示全部楼层
设计模式解决环的问题一般是采用抽象一个接口层次出来,让相互直接引用的类改为引用对发的抽象接口,如果采用这个模型
那么接口和实现之间就需要一个很严格的规则来避免实体先于接口被释放,这个倒是可以参考COM的规则.

这样增加了复杂性,是否会引入更多的问题了?
您需要登录后才可以回帖 登录 | 用户注册

本版积分规则

Archiver|手机版|小黑屋|ACE Developer ( 京ICP备06055248号 )

GMT+8, 2024-5-22 03:58 , Processed in 0.025996 second(s), 6 queries , Redis On.

Powered by Discuz! X3.5

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表