游戏开发论坛

 找回密码
 立即注册
搜索
楼主: qinglan

游戏服务器技术交流

[复制链接]

7

主题

82

帖子

110

积分

注册会员

Rank: 2

积分
110
QQ
 楼主| 发表于 2007-9-21 09:35:00 | 显示全部楼层

Re:游戏服务器技术交流

我也没有说队列长了会增大锁碰撞的机会

我说的是读线程和写线程都对同一个队列操作会引起频繁的锁碰撞

而分多个队列后,读和写都只针对自己的队列,这时就算所有的操作都加锁,也是没有碰撞的,碰撞只有可能发生在去容器中调换队列时和两个线程互换队列时

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-21 12:11:00 | 显示全部楼层

Re:游戏服务器技术交流

关于队列的问题,我以前一直在想是否可能构建一个专门为多线程设计的队列,而不是现在这样以队列为基本单位进行加锁。我觉得大多数时候,队首出队和队尾入队是没有多少冲突的,因为可以认为大多数时候队首和队尾之间是有其他节点来分隔的,但是实际尝试的时候发现由于入队和出队的操纵需要操纵一些共有的指针(比如队首指针、队尾指针),队列长度的判断也需要操纵一些共有的指针,因此要达到理论上那么少的冲突一直做不到,所以我现在也是对整个队列加锁。但是毕竟理论上当队列中间有节点分隔队首和队尾的时候入队和出队是不应该冲突的,不知道大家有什么办法或思路。

另外关于IO缓存的问题。对于一个网络连接,recv和send都是系统调用,而且它们都只支持线性缓存而不支持环形缓存。如果要用循环缓存是否就必然会增加这些系统调用的调用次数?系统调用的开销似乎并不低。我现在是每个连接使用线性缓存,每次epoll通知有数据之后只调用一次recv,提供给recv的缓存是这个线性缓存剩下的那一段,读完之后立即判断缓存中是否有了完整的数据包,有的话就调用函数把它还原为一个Message对象并把这个对象加入到一个队列里,然后把剩余的数据memcpy到缓存的头部。而且循环缓存还有个问题,就是其中一个完整的数据包的数据可能不是连续的,而是分布在内存区域头尾的分开的两段,而且后面一段其实是数据包的前面一段,这样不连续的数据要还原为struct或者对象都很麻烦,特别是如果一个4字节的int被分开了,前2个字节在缓存尾部,后2个字节在缓存头部,那么要把这个数据还原为int就很麻烦,还是避免不了memcpy……毕竟环形缓存在底层仍然是线性的,要把环形缓存封装为一个流可能会很麻烦。

89

主题

822

帖子

847

积分

高级会员

Rank: 4

积分
847
发表于 2007-9-21 13:27:00 | 显示全部楼层

Re:游戏服务器技术交流

不知道是谁发明的环形缓存,我觉得这种东西用于吃回转寿司还行,用在高速运行的服务器估计有点问题,我没试过,我只发表一下个人看法。

第一2个指针只能用于2个线程,如果用于超过2个线程,那么对这2个指针的访问就要加锁,碰撞是一样的。
第二要保证读取的指针永远不能越过写入的指针,对于每秒循环千万次的计算机来说,要做到这一点只能依赖于每次移动读取指针的时候判断写入的指针是否在前,在判断的同时要求写入的指针是静止的,就是说要对写入指针加锁。
第三环型缓冲区要变长比较麻烦,如果环型队列满了,必须增加新的空间,这一点不如线形队列方便。

我个人觉得缓冲区停留在内存级别就可以了。

这是个比较有意思的问题,我觉得服务器的问题不在于使用什么架构,因为架构总是随着不同的应用在变化着,而在于我们如何组织数据的传输和疏导,有点像交警。

6

主题

471

帖子

1047

积分

金牌会员

Rank: 6Rank: 6

积分
1047
发表于 2007-9-21 14:04:00 | 显示全部楼层

Re: Re:游戏服务器技术交流

sjinny: Re:游戏服务器技术交流

关于队列的问题,我以前一直在想是否可能构建一个专门为多线程设计的队列,而不是现在这样以队列为基本单位进行加锁。我觉得大多数时候,队首出队和队尾入队是没有多少冲突的,因为可以认为大多数时候队首和队尾之间是有其他节点来分隔的,但是实际尝试的时候发现由于入队和出队的操纵需要操纵一些共有的指针(比如队首指针、队尾指针),队列长度的判断也需要操纵一些共有的指针,因此要达到理论上那么少的冲突一直做不到,所以我现在也是对整个队列加锁。但是毕竟理论上当队列中间有节点分隔队首和队尾的时候入队和出队是不应该冲突的,不知道大家有什么办法或思路。

在处理消息时也对队列加锁?
我一般lock消息队列pop指定数量的消息放入另个执行队列(该队列不加锁).然后pop执行队列中的消息进行处理.

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-21 14:23:00 | 显示全部楼层

Re:游戏服务器技术交流

汗……可能我表达的有问题,我只是觉得即使只是出队入队,应该不需要每次都加锁的……

6

主题

471

帖子

1047

积分

金牌会员

Rank: 6Rank: 6

积分
1047
发表于 2007-9-21 14:44:00 | 显示全部楼层

Re:游戏服务器技术交流

多线程对同一队列出入加锁是必须的,这点开销不算什么.
(网络线程+消息执行线程决定同时竞争数量,执行线程一般是周期性锁定,时间跨度比较长,
所以都是网络线程在竞争队列).
服务器压力大部分都是由send引起的,尽量减小减少数据发送才能对性能有所提升.

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-21 16:00:00 | 显示全部楼层

Re:游戏服务器技术交流

受教了……请教一下一般做软件的压力测试有些什么理论、方法和工具吗?我从没做过这些,但是越来越觉得自己的软件的确需要做压力测试,不然软件做得到底怎么样心里根本没底。我只有一台计算机,可以做服务器端的压力测试吗?

6

主题

471

帖子

1047

积分

金牌会员

Rank: 6Rank: 6

积分
1047
发表于 2007-9-21 16:25:00 | 显示全部楼层

Re: Re:游戏服务器技术交流

sjinny: Re:游戏服务器技术交流

受教了……请教一下一般做软件的压力测试有些什么理论、方法和工具吗?我从没做过这些,但是越来越觉得自己...

我是单独给项目写了压力测试程序,用iocp做了底层,逻辑上是简化的客户端,省略了大部分处理,但数据收发是按照正常客户端处理.
一台机器也能测,但只能测下服务器逻辑是否会当机,本机网络数据传送几乎是直接copy
要做压力测试最好有外网服务器,局域网也行.

149

主题

4981

帖子

5033

积分

论坛元老

Rank: 8Rank: 8

积分
5033
QQ
发表于 2007-9-21 17:24:00 | 显示全部楼层

Re:游戏服务器技术交流

汗……………………只有一台电脑……穷啊……  T.T
不过既然传送数据是由软件控制的,有没有什么软件能够模拟网络延时并能透明的与已有软件整合呢?那样就可以单机进行测试了,而且测试环境还是可控的……

0

主题

172

帖子

176

积分

注册会员

Rank: 2

积分
176
发表于 2007-9-22 12:59:00 | 显示全部楼层

Re:游戏服务器技术交流

队列容器,里面有多个队列,在我看来,是为了解决逻辑线程频繁PopMsg,使得IO线程与逻辑线程频繁锁冲突的问题。(对于很多人来说,恐怕逻辑线程都是近似于不阻塞死循环一样在PopMsg查询是否有消息)


以队列内部操作为单位加锁,用起来恐怕很麻烦,有不少类似
if(!empty())
   pop()
else ....;
的操作,我曾经写过empty,pop为单位加锁,结果实际中就遇到empy为false,执行到pop时就是空队列了 (??,类似这种问题,在多核心,多CPU机器上更是频发。


对于bigbook2000说的“这是个比较有意思的问题,我觉得服务器的问题不在于使用什么架构,因为架构总是随着不同的应用在变化着,而在于我们如何组织数据的传输和疏导,有点像交警。”
个人认为,服务器还是在于架构。这话说的就像“程序不在于怎么去设计编写,因为程序随着不同的应用在变化,而在于我们怎么去开发更加很好很强大的新语言”  ^__^
您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

作品发布|文章投稿|广告合作|关于本站|游戏开发论坛 ( 闽ICP备17032699号-3 )

GMT+8, 2025-2-25 23:33

Powered by Discuz! X3.4

Copyright © 2001-2021, Tencent Cloud.

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