【问题标题】:FD_SET causing seg faultFD_SET 导致段错误
【发布时间】:2013-12-16 18:37:42
【问题描述】:

我遇到了FD_SET 正在使我的程序崩溃的问题。我正在从 boost Boost ASIO sample HTTP Server 运行示例代码。在请求处理程序中,我放置了一个第三方 api,最终进行以下调用:

fd_set fds; 
FD_ZERO(&fds);
FD_SET(sockfd, &fds);

我的程序似乎在FD_SET 上崩溃了。是否存在从不同线程调用FD_SET 会导致段错误的情况?我不确定FD_SET 究竟是如何工作的,我的直觉是我在一个已经在使用的fd 上调用FD_SET。这会导致问题吗?

sockfd 是一个类成员,每次请求进来时都会创建,所以我不应该在线程之间共享sockfd 变量。

【问题讨论】:

  • “看起来像”是什么意思?不能用调试器确定吗?
  • 您是否检查过sockfd 是正数,并且小于FD_SETSIZE
  • FD_SET() 实际上只是在无符号整数数组中设置一个位。使用上面的代码,FD_SET 失败或搞砸的最可能原因是sockfd 超出范围,例如,因为它无效或因为可用套接字的系统参数大于@ 中可用的位987654335@.
  • 问题是增加系统上可用文件描述符的数量并不会改变实现这些类的 C 库。理想情况下,您可以将代码更改为与相对低效的select() 不同的代码,以使用poll()epoll()。你的问题是一旦超过FD_SETSIZE,被设置的位就在不相关的内存中,这只是缓冲区溢出的一种形式。
  • @Eumcoz:您可以使用pollepoll,或者通过Boost 库在更高级别上工作。我不知道有没有办法增加FD_SETSIZE,因为我自己不理会select

标签: c++ multithreading boost segmentation-fault file-descriptor


【解决方案1】:

在每秒 1000 个请求时,您很可能会超过 FD_SETSIZE 限制(在 Linux 上通常为 1024),这会导致 undefined behavior

fd_set 是一个固定大小的缓冲区。执行 FD_CLR()FD_SET() fd 的值为负或等于或大于 FD_SETSIZE 将导致未定义的行为。此外,POSIX 要求 fd 是一个有效的文件描述符。

您应该考虑使用pollepoll 或更高级别的库,例如Boost Asio。这些选择中的任何一个都不会受到select的限制。

【讨论】:

    猜你喜欢
    • 2015-09-03
    • 2012-08-17
    • 1970-01-01
    • 2011-01-11
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多