关于select 与多线程的疑问

GreenWaterBlueSky 2008-05-27 09:56:27
我想同时监控很多个连接(几千个),所以我打算分成多个线程,每个线程用select监控一部分(尝试是可以的),但是我查资料感觉好像都不建议这样用;不知道问什么,请各位大虾指点下;谢谢
...全文
440 11 打赏 收藏 转发到动态 举报
AI 作业
写回复
用AI写文章
11 条回复
切换为时间正序
请发表友善的回复…
发表回复
wjlsmail 2008-07-14
  • 打赏
  • 举报
回复
Study, 将所有socket放在一个 select 集合中是多见一些。
Treazy 2008-05-27
  • 打赏
  • 举报
回复
[Quote=引用 8 楼 GreenWaterBlueSky 的回复:]
但是,如果用一个select监控所有的,那么当有一个连接的请求,就要循环所有连接来判断是那个连接的请求,但是分成几个线程select,
那么来一个连接,我只要循环这个子线程的连接,这样不是应该效率高些吗
[/Quote]

你可以去试试,作个性能对比

这样就知道是否可行了!

原则上你可以开最多的线程来处理一切,这样什么问题都没了,

但是你的cpu不是只给你一个程序使用的

系统负荷的轻重,你也是需要考虑的。所以怎么写,还是要结合具体情况和应用环境的!
GreenWaterBlueSky 2008-05-27
  • 打赏
  • 举报
回复
但是,如果用一个select监控所有的,那么当有一个连接的请求,就要循环所有连接来判断是那个连接的请求,但是分成几个线程select,
那么来一个连接,我只要循环这个子线程的连接,这样不是应该效率高些吗
Treazy 2008-05-27
  • 打赏
  • 举报
回复
[Quote=引用 5 楼 GreenWaterBlueSky 的回复:]
我最不明白的是,为什么多数人都建议用select监控所有的连接,Treazy能不能给点说明,多谢了
[/Quote]


//处理32 个以上的打开文件。howmany 、fd_set 和NFDBITS 都在<sys/types.h> 中定义。
#include <sys/param.h>
#include <sys/types.h>
#include <sys/time.h>

#define MASK(f) (1 << (f))
#define NTTYS NOFILE - 3
#define NWORDS howmany(FD_SETSIZE, NFDBITS)

int tty[NTTYS];
int ttymask[NTTYS];
struct fd_set readmask, readfds;
int nfound, i, j, k;
struct timeval timeout;
.....
/* First open each terminal for reading and put the
* file descriptors into array tty[NTTYS]. The code
* for opening the terminals is not shown here.*/
for (k=0; k < NWORDS; k++)
readmask.fds_bits[k] = 0;
for (i=0, k=0; i < NTTYS && k < NWORDS; k++)
for (j=0; j < NFDBITS && i < NTTYS; j++, i++) {
ttymask[i] = MASK(tty[i]);
readmask.fds_bits[k] |= ttymask[i];
}
timeout.tv_sec = 5;
timeout.tv_usec = 0;
for (k=0; k < NWORDS; k++)
readfds.fds_bits[k] = readmask.fds_bits[k];
/* select on NTTYS+3 file descriptors if stdin, stdout
* and stderr are also open
*/
if ((nfound = select (NTTYS+3, &readfds, 0, 0, &timeout)) == -1)
perror ("select failed");
else if (nfound == 0)
printf ("select timed out \n");
else for (i=0, k=0; i < NTTYS && k < NWORDS; k++)
for (j=0; j < NFDBITS && i < NTTYS; j++, i++)
if (ttymask[i] & readfds.fds_bits[k])
/* Read from tty[i]. The code for reading
* is not shown here.
*/
else printf ("tty[%d] is not ready for reading \n",i);

......
Treazy 2008-05-27
  • 打赏
  • 举报
回复
[Quote=引用 4 楼 GreenWaterBlueSky 的回复:]
一般是建议只一个select管理所有的连接
[/Quote]

我说的比较好的设计就是指这个!

而你说的那种就是我说的那种设计很不好的!

GreenWaterBlueSky 2008-05-27
  • 打赏
  • 举报
回复
我最不明白的是,为什么多数人都建议用select监控所有的连接,Treazy能不能给点说明,多谢了
GreenWaterBlueSky 2008-05-27
  • 打赏
  • 举报
回复
我是这样,主线程只管接受连接,收到连接就把它丢给连接最少的子线程,子线程负责读写数据(用select),数据处理逻辑是比较简单的,也没有什么大的循环,就是写库,而且超时我也不是在这里判断,另外一个程序来判断,查询数据库如果某个连接很久没信息就通知服务器释放该连接;
但是我在网上查一般说的都是不建议这样用;一般是建议只一个select管理所有的连接
Treazy 2008-05-27
  • 打赏
  • 举报
回复
[Quote=引用 2 楼 Treazy 的回复:]
几千个,分成多线程

那一个线程中需要监控至少几百个

首先在效率上已经慢了

使用循环遍历的方法去监控,那你势必需要设置监控超时,那几百个的超时时间,一次循环完,能做到实时响应吗?

举个很简单的例子,如果你在一个线程中监控500个

每个设置超时1s那500个就是500m,如果第一个连接开始未连接等待超时,等到第2秒的时候它就连接上请求读写了

那这个时候程序却必须要继续轮询剩余的499个,根本无法做…
[/Quote]

我说的这个情况可能不是很好,因为这是设计上的缺陷

如果换种设计比较好的方法,我们来使用一个readfds,让select来等待,超时仍然是1s
用while循环一直select,那当其中一个连接上时,我们发现了,那就需要遍历才能发现你的确定的连接对象
而这个遍历次数和时间确是和你的监控文件的个数成线性增长的

所以当监控对象增加时,程序会变的慢,而且在设置readfds时其实已经人为给予了不同连接的priority了
这都是问题,但这些问题只是在于用select调用太多的文件描述符 而导致的!
Treazy 2008-05-27
  • 打赏
  • 举报
回复
几千个,分成多线程

那一个线程中需要监控至少几百个

首先在效率上已经慢了

使用循环遍历的方法去监控,那你势必需要设置监控超时,那几百个的超时时间,一次循环完,能做到实时响应吗?

举个很简单的例子,如果你在一个线程中监控500个

每个设置超时1s那500个就是500m,如果第一个连接开始未连接等待超时,等到第2秒的时候它就连接上请求读写了

那这个时候程序却必须要继续轮询剩余的499个,根本无法做到preemption,也就是先来先响应!

GreenWaterBlueSky 2008-05-27
  • 打赏
  • 举报
回复
怎么没有人啊
GreenWaterBlueSky 2008-05-27
  • 打赏
  • 举报
回复
谢谢

5,530

社区成员

发帖
与我相关
我的任务
社区描述
C/C++ 模式及实现
社区管理员
  • 模式及实现社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧