use*_*574 6 sockets tcp posix-select
我正在使用非阻塞套接字(C/C++)编写网络通信程序select
.该程序非常大,所以我无法上传源代码.在非常激进的测试会话中,我使用测试代码频繁地打开和关闭TCP和UDP.总是最终一端没有响应并且CPU使用率超过98或99%.然后我用gdb来附加."bt"显示以下内容:
0x00007f1b71b59ac3 in __select_nocancel () at ../sysdeps/unix/syscall-template.S:82
82 ../sysdeps/unix/syscall-template.S: No such file or directory.
in ../sysdeps/unix/syscall-template.S
Run Code Online (Sandbox Code Playgroud)
它可能是什么类型的错误?
$ uname -a
Linux kiosk2 2.6.32-34-generic #77-Ubuntu SMP Tue Sep 13 19:39:17 UTC 2011 x86_64 GNU/Linux
Run Code Online (Sandbox Code Playgroud)
Jer*_*ner 34
没有看代码就不可能说,但是当基于选择的循环开始以~100%的CPU使用率开始旋转时,这是因为你被告知select()
要观看的一个或多个套接字是可以读取的(和/或准备好的) -for-write)这样就可以立即select()
返回而不是阻塞......但是代码忽略了实际recv()
(或send()
)该套接字上的任何数据.在无法读取/写入任何内容之后,您的事件循环将尝试通过select()
再次调用返回休眠状态,但当然套接字的数据(或缓冲区空间,在准备写入的情况下)仍然在那里等待处理,所以select()
马上再次返回,有缺陷的代码忽略了write()
再次读取(或),并且我们周围的速度最快:)
另一种可能性是你传递一个超时值select()
为零或接近于零,导致select()
即使没有套接字准备好任何东西也能很快返回...这通常发生在人们忘记重新初始化时每次调用之前的timeval结构select()
.您需要每次重新初始化timeval结构,因为某些实现select()
将在返回之前修改它.
我的建议是在你打电话之前和之后立即放一些printf(或你最喜欢的等价物)select()
,并在重现故障时观察输出.这将显示旋转是在一次调用中发生的select()
,还是某些东西导致select()
一次又一次地返回.
归档时间: |
|
查看次数: |
5297 次 |
最近记录: |