- r - 以节省内存的方式增长 data.frame
- ruby-on-rails - ruby/ruby on rails 内存泄漏检测
- android - 无法解析导入android.support.v7.app
- UNIX 域套接字与共享内存(映射文件)
我有一个 jabber 服务器应用程序和另一个用 C++ 编写的 jabber 客户端应用程序。
当客户端接收和发送大量消息(每秒超过 20 条)时,选择会卡住并且永远不会返回。
使用 netstat,socket 仍然连接在 linux 上,使用 tcpdump,消息仍然发送到客户端,但选择永远不会返回。
这里是选择的代码:
bool ConnectionTCPBase::dataAvailable( int timeout )
{
if( m_socket < 0 )
return true; // let recv() catch the closed fd
fd_set fds;
struct timeval tv;
FD_ZERO( &fds );
// the following causes a C4127 warning in VC++ Express 2008 and possibly other versions.
// however, the reason for the warning can't be fixed in gloox.
FD_SET( m_socket, &fds );
tv.tv_sec = timeout / 1000000;
tv.tv_usec = timeout % 1000000;
return ( ( select( m_socket + 1, &fds, 0, 0, timeout == -1 ? 0 : &tv ) > 0 )
&& FD_ISSET( m_socket, &fds ) != 0 );
}
死锁与 gdb 有关:
Thread 2 (Thread 0x7fe226ac2700 (LWP 10774)):
#0 0x00007fe224711ff3 in select () at ../sysdeps/unix/syscall-template.S:82
#1 0x00000000004706a9 in gloox::ConnectionTCPBase::dataAvailable (this=0xcaeb60, timeout=<value optimized out>) at connectiontcpbase.cpp:103
#2 0x000000000046c4cb in gloox::ConnectionTCPClient::recv (this=0xcaeb60, timeout=10) at connectiontcpclient.cpp:131
#3 0x0000000000471476 in gloox::ConnectionTLS::recv (this=0xd1a950, timeout=648813712) at connectiontls.cpp:89
#4 0x00000000004324cc in glooxd::C2S::recv (this=0xc5d120, timeout=10) at c2s.cpp:124
#5 0x0000000000435ced in glooxd::C2S::run (this=0xc5d120) at c2s.cpp:75
#6 0x000000000042d789 in CNetwork::run (this=0xc56df0) at src/Network.cpp:343
#7 0x000000000043115f in threading::ThreadManager::threadWorker (data=0xc56e10) at src/ThreadManager.cpp:15
#8 0x00007fe2249bc9ca in start_thread (arg=<value optimized out>) at pthread_create.c:300
#9 0x00007fe22471970d in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:112
#10 0x0000000000000000 in ?? ()
你知道什么会导致 select 停止接收消息,即使我们仍在向他发送消息。当通过套接字接收和发送大量消息时,linux 中是否有缓冲区限制?
谢谢
最佳答案
有几种可能性。
超过FD_SETSIZE
您的代码正在检查是否存在负文件描述符,但不会检查是否超过上限 FD_SETSIZE
(通常为 1024)。每当发生这种情况时,您的代码就是
fd_set
到 select
这将导致挂起假设您不需要那么多并发打开的文件描述符,解决方案可能包括找到一个消除文件描述符泄漏的方法,尤其是堆栈上处理废弃描述符关闭的代码。
您的代码中存在可疑注释,表明可能存在泄漏:
// let recv() catch the closed fd
如果这条评论意味着有人设置了m_socket
到 -1 并希望 recv
将捕获关闭的套接字并关闭它,谁知道呢,也许我们正在关闭 -1 而不是真正关闭的套接字。 (请注意网络级别关闭和文件描述符级别关闭之间的区别,后者需要单独的 close
调用。)
这也可以通过移至 poll
来解决。但是操作系统强加的一些其他限制使这条路线非常具有挑战性。
带外数据
你说服务器正在“发送”数据。如果这意味着数据是使用 send
发送的调用(而不是 write
调用),使用 strace
确定发送标志参数。如果MSG_OOB
使用标志,数据作为带外数据到达 - 而您的 select
在您传递 fds
的拷贝之前,调用不会注意到这些作为另一个参数。
fd_set fds_copy = fds;
select( m_socket + 1, &fds, 0, &fds_copy, timeout == -1 ? 0 : &tv )
进程饥饿
如果盒子严重重载,服务器将在没有任何阻塞调用的情况下执行,并且具有实时优先级(使用 top
来检查) - 而客户端不是 - 客户端可能会饿死。
暂停进程
客户端理论上可能会被 SIGSTOP
停止.您可能知道是否是这种情况,按下某处 ctrl-Z 或让某个特定进程对客户端进行控制而不是您自己启动它。
关于c++ - 套接字选择死锁的可能原因,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11179040/
是否有某种方法可以使用 JPA 或 Hibernate Crtiteria API 来表示这种 SQL?或者我应该将其作为 native 执行吗? SELECT A.X FROM (SELECT X,
在查询中, select id,name,feature,marks from (....) 我想删除其 id 在另一个 select 语句中存在的那些。 从 (...) 中选择 id 我是 sql
我想响应用户在 select 元素中选择一个项目。然而这个 jQuery: $('#platypusDropDown').select(function () { alert('You sel
这个问题在这里已经有了答案: SQL select only rows with max value on a column [duplicate] (27 个回答) 关闭8年前。 我正在学习 SQL
This question already has answers here: “Notice: Undefined variable”, “Notice: Undefined index”, and
我在 php 脚本中调用 SQL。有时“DE”中没有值,如果是这种情况我想从“EN”中获取值 应该是这样的,但不是这样的 IF (EXISTS (SELECT epf_application_deta
这可能是一个奇怪的问题,但不知道如何研究它。执行以下查询时: SELECT Foo.col1, Foo.col2, Foo.col3 FROM Foo INNER JOIN Bar ON
如何在使用 Camera.DestinationType.FILE_URI. 时在 phonegap camera API 中同时选择或拾取多个图像我能够一次只选择一张图像。我可以使用 this 在
这是一个纯粹的学术问题。这两个陈述实际上是否相同? IF EXISTS (SELECT TOP 1 1 FROM Table1) SELECT 1 ELSE SELECT 0 相对 IF EXIS
我使用 JSoup 来解析 HTML 响应。我有多个 Div 标签。我必须根据 ID 选择 Div 标签。 我的伪代码是这样的 Document divTag = Jsoup.connect(link
我正在处理一个具有多个选择框的表单。当用户从 selectbox1 中选择一个选项时,我需要 selectbox2 active 的另一个值。同样,当他选择 selectbox2 的另一个值时,我需要
Acme Inc. Christa Woods Charlotte Freeman Jeffrey Walton Ella Hubbard Se
我有一个login.html其中form定义如下: First Initial Plus Last Name : 我的do_authorize如下: "; pri
$.get( 'http://www.ufilme.ro/api/load/maron_online/470', function(data
我有一个下拉列表“磅”、“克”、“千克”和“盎司”。我想要这样一种情况,当我选择 gram 来执行一个函数时,当我在输入字段中输入一个值时,当我选择 pounds 时,我想要另一个函数来执行时我在输入
我有一个 GLSL 着色器,它从输入纹理的 channel 之一(例如 R)读取,然后写入输出纹理中的同一 channel 。该 channel 必须由用户选择。 我现在能想到的就是使用一个 int
我想根据下拉列表中的选定值生成输入文本框。 Options 2 3 4 5 就在这个选择框之后,一些输入字段应该按照选定的数字出现。 最佳答案 我建议您使用响应式(Reac
我是 SQL 新手,我想问一下如何根据首选项和分组选择条目。 +----------+----------+------+ | ENTRY_ID | ROUTE_ID | TYPE | +------
我有以下表结构: CREATE TABLE [dbo].[UTS_USERCLIENT_MAPPING_USER_LIST] ( [MAPPING_ID] [int] IDENTITY(1,1
我在移除不必要的床单时遇到了问题。我查看了不同的论坛并将不同的解决方案混合在一起。 此宏删除工作表(第一张工作表除外)。 Sub wrong() Dim sht As Object Applicati
我是一名优秀的程序员,十分优秀!