A
Another_eYes
Unregistered / Unconfirmed
GUEST, unregistred user!
某个服务程序需要监听6-8个端口,并且向3-5台服务器转发数据,目标:每台机器峰值支持1000-1500连接。原先使用消息模式,开6-8个进程,每个进程监听一个端口并向特定服务器转发数据。现改为完成端口模式,一个进程同时监听6-8个端口,另有3-5个client连接连到不同服务器用于转发数据,工作线程数为cpu数×2+2(机器配双cpu并超线程成4cpu)。由于在转发数据时必须对数据进行过滤与处理,因此必须保存各个client的当前应用状态,这样在转发数据与处理时必然存在线程间的冲突。
冲突点依发生可能性排列主要有:
1.可能同时有多个线程向同一个socket发送数据,必须同步这些发送请求;
2.某一线程正在处理读到的客户端数据时,另一线程被触发并处理服务器发来的数据,而这些数据极有可能属于正在处理的这个客户端;
3.某一线程正在处理客户端或服务器发送来的数据时,另一线程被触发处理客户端断开连接请求并开始释放资源;
4.第一个客户端断开连接并成功释放资源,之后第二个客户端建立连接并且socket handle与前一个被释放的相同,而此时server发来第一个客户端某次请求的回应数据,造成第二个客户端收到的数据发生紊乱(尽管可能性极小,但实践中却发生了)。
第一次的解决方案: 每个client连接后都创建两个Critical Section,一个用于同步send,另一个用于同步read,client断开连接时释放这两个CriticalSection。实际效果:700-800连接,峰值cpu占用<5%,大部分时间0%-1%,客户端运行流畅。运行10-40分钟左右收发数据开始下降(看表现似乎某些客户端的读或写死锁)继续运行一段时间整个程序死锁(无法关闭)或崩溃(彻底消失)
第二次:每个client连接后都从全局分配的一个Critical Section列表中获取两个用于同步read和send,client断开连接时将这两个Critical Section归还全局列表供以后使用,另外单独开了一个线程同步所有的断开连接操作。实际效果:700-800连接,峰值cpu<5%,大部分时间0%-2%,客户端运行流畅。运行不超过20分钟部分监听端口或连接服务器端口的read或write死锁(收或发送字节数变为0),但程序可以正常退出。
第三次:不使用Critical Section,而是通过自己写代码实现同步锁(主要就是while+sleep(0))。实际效果:700-800连接,峰值cpu<10%,大部分时间0%-2%,客户端运行有延时,效率与消息模式相同(甚至更低一点)。运行4-5小时死锁。程序能正常退出。
第四次:完成端口工作线程数减少一半,另一半创建处理线程,每个client连接关联到某个处理线程,在client连接的周期中一直由这个线程处理这个client的所有操作,完成端口工作线程通过postthreadmessage调度相应的处理线程处理数据。实际效果:700-800连接,峰值cpu>30%,大部分时间25-30%,运行1天半没有任何问题。客户端延时严重,效率甚至不如消息模式。
各位大拿有什么好的办法解决这个问题?
冲突点依发生可能性排列主要有:
1.可能同时有多个线程向同一个socket发送数据,必须同步这些发送请求;
2.某一线程正在处理读到的客户端数据时,另一线程被触发并处理服务器发来的数据,而这些数据极有可能属于正在处理的这个客户端;
3.某一线程正在处理客户端或服务器发送来的数据时,另一线程被触发处理客户端断开连接请求并开始释放资源;
4.第一个客户端断开连接并成功释放资源,之后第二个客户端建立连接并且socket handle与前一个被释放的相同,而此时server发来第一个客户端某次请求的回应数据,造成第二个客户端收到的数据发生紊乱(尽管可能性极小,但实践中却发生了)。
第一次的解决方案: 每个client连接后都创建两个Critical Section,一个用于同步send,另一个用于同步read,client断开连接时释放这两个CriticalSection。实际效果:700-800连接,峰值cpu占用<5%,大部分时间0%-1%,客户端运行流畅。运行10-40分钟左右收发数据开始下降(看表现似乎某些客户端的读或写死锁)继续运行一段时间整个程序死锁(无法关闭)或崩溃(彻底消失)
第二次:每个client连接后都从全局分配的一个Critical Section列表中获取两个用于同步read和send,client断开连接时将这两个Critical Section归还全局列表供以后使用,另外单独开了一个线程同步所有的断开连接操作。实际效果:700-800连接,峰值cpu<5%,大部分时间0%-2%,客户端运行流畅。运行不超过20分钟部分监听端口或连接服务器端口的read或write死锁(收或发送字节数变为0),但程序可以正常退出。
第三次:不使用Critical Section,而是通过自己写代码实现同步锁(主要就是while+sleep(0))。实际效果:700-800连接,峰值cpu<10%,大部分时间0%-2%,客户端运行有延时,效率与消息模式相同(甚至更低一点)。运行4-5小时死锁。程序能正常退出。
第四次:完成端口工作线程数减少一半,另一半创建处理线程,每个client连接关联到某个处理线程,在client连接的周期中一直由这个线程处理这个client的所有操作,完成端口工作线程通过postthreadmessage调度相应的处理线程处理数据。实际效果:700-800连接,峰值cpu>30%,大部分时间25-30%,运行1天半没有任何问题。客户端延时严重,效率甚至不如消息模式。
各位大拿有什么好的办法解决这个问题?