存储套接字信息随机访问速度
目前情况:我设置了一个linux服务器(用于与陌生人聊天),我有一个关于效率的问题。
目前,我正在一个简单的管理器类中使用地图来将两个陌生人配对:
int sockManager::set_pair(int me, int them) {
if (them != -1) {
pairs[me] = them;
pairs[them] = me;
return 1;
}
return -1;
}
int sockManager::get_pair(int me) {
return pairs[me];
}
void sockManager::add_single(int me) {
pairs[me] = -1;
}
void sockManager::remove_single(int me) {
if (pairs[me] != -1)
pairs[pairs[me]] = -1;
pairs.erase(me);
}
int sockManager::find_unconnected(int me) {
if (pairs[me] != -1)
return pairs[me];
for (iter = pairs.begin();iter!=pairs.end();iter++){
if (iter->second == -1 && iter->first != me)
return iter->first;
}
return -1;
}
int sockManager::get_size(){
return pairs.size();
}
我使用此管理器类的原因是为了可扩展性。例如,此时我想改变寻找两个客户端连接的方式。我想要一个“需要连接” 标志,以及一个简单的线程来不断运行并找到要连接的客户端,当客户端无法连接时,如果时间已经超过x秒,请向他们发送有趣的说法或其他东西(让他们开心)我也需要确保客户端不会连接到与其 IP 地址相同的人...
问题如下: 我使用映射来存储每个套接字及其相应的伙伴。是否有另一种更快的方法来存储每个套接字和伙伴组合? (对于随机访问,例如查找 int[socket] 与 map 方法的速度。) {是否使用成对的结构数组是我最初的问题,然后我意识到这太愚蠢了...文件描述符不会每次都增加 1,所以认为数组会加快速度是完全没有用的上}
主观问题: 我想为每个连接存储标志,您认为最好、最容易扩展的方法是将映射对的值(而不是键)放入一个包含必要信息(合作伙伴套接字、连接标志)的结构中吗? ,标记为...)或者我应该制作另一张地图,专门将标记成员作为值?内存不会有问题。
第三个更扎实的[&&稍微不相关]问题: 我正在使用 FD_Set 和 select() 函数,并且我读到它对于大量 FD 来说非常慢(我知道它最多可以处理 1024,但这同样适用于 poll()) 我该怎么办实施基于事件的系统来侦听来自用户的传入数据? (操作系统:ubuntu linux)并且速度会快多少?我已经对我的服务器进行了压力测试,我可以通过网络处理数百个客户端,而用户端不会出现明显的速度减慢。我想一次支持 3k 以上。
通过提出问题并意识到我要问多少愚蠢的问题,我比花几个小时阅读一些东西了解了更多......
Current situation: I have a linux server (for chatting with strangers) set up and I have a question on efficiency.
Currently I'm using a map in a simple manager class to pair up two strangers:
int sockManager::set_pair(int me, int them) {
if (them != -1) {
pairs[me] = them;
pairs[them] = me;
return 1;
}
return -1;
}
int sockManager::get_pair(int me) {
return pairs[me];
}
void sockManager::add_single(int me) {
pairs[me] = -1;
}
void sockManager::remove_single(int me) {
if (pairs[me] != -1)
pairs[pairs[me]] = -1;
pairs.erase(me);
}
int sockManager::find_unconnected(int me) {
if (pairs[me] != -1)
return pairs[me];
for (iter = pairs.begin();iter!=pairs.end();iter++){
if (iter->second == -1 && iter->first != me)
return iter->first;
}
return -1;
}
int sockManager::get_size(){
return pairs.size();
}
The reason I'm using this manager class is for expandability. For instance at this moment I want to change the way I find two clients to connect. I'd like to have a "needs to connect"
flag, and a simple thread to constantly run through and find clients to connect, when a client can't be connected, if the time has been more than x seconds, send them a funny saying or something (keep them entertained) I also need to make sure that a client isn't connecting to someone with the same IP address as theirs...
Here's the question:
I'm using a map to store each socket and it's corresponding partner. Is there another, faster, way to store each socket and partner combination? (for random access, like the speed to lookup an int[socket] vs the map method.)
{Whether using an array of structs for pairs was my initial question, then I realized that would be way dumb... The file descriptors don't go up by 1 each time so it would be completely useless to think an array would speed things up}
Subjective(ish) question:
I would like to store flags for each connection, do you think the best and most easily expandable method would be to make the value (as opposed to key) of the map pair into a struct holding the necessary info (partner socket, flag to connect, flag to ...) or should I make another map with specifically the flag members as the value? Memory won't be an issue.
Third More Solid [&& slightly unrelated] question:
I am using an FD_Set with the select() function, and I've read it's quite slow with large numbers of FD's (I know it can handle a max of 1024, but the same applies to poll()) How would I go about implementing an event-based system to listen for incoming data from users? (OS: ubuntu linux) and How much faster will it be? I've stress tested my server as it is and I can handle several hundred clients across the network without a noticeable slowdown on the user's side. I'd like to support upwards of 3k at a time.
I figured out more by asking the question and realizing how many dumb questions I was about to ask than reading up on stuff for hours...
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
通常,尝试解决 c10k 问题 的人们将使用 libevent 或 MTasker。线程通常可以让你在没有太多麻烦的情况下减少数百个内存,但在某些时候内存使用量会变得非常有限。基于事件的编程通常可以让服务器扩展到数千台,但这取决于许多因素。
Typically, people trying to solve the c10k problem will use an event-handling loop as provided by libevent or MTasker. Threading will typically get you in the low-hundreds without too much hassle, but at some point the memory usage gets very restrictive. Event-based programming typically lets servers scale into the thousands, but it depends on many factors.