2

我的代码打开了超过 256 个文件句柄,所以当我在 Solaris 机器上运行它时,我最终会出现“超出文件处理程序限制”错误。

我对此有两个问题

1) 这个限制是只针对 32 位软件还是 64 位软件也受此限制。我用谷歌搜索了一下,发现 64 位软件没有这个限制。(http://developers.sun.com/solaris/articles/stdio_256.html)但是我构建了 64 位静态对象,当我使用它时给出错误。实际上 64 位软件意味着什么?

2)如上面的链接中给出的,我使用 ulimit 来增加文件处理程序限制(在运行时,我的意思是在运行命令之前),导出扩展文件库并且我没有收到任何错误。我们必须做的 Linux ?

谢谢 DL 库马尔

4

5 回答 5

3

我以前遇到过这种情况。据我所知,这实际上是 solaris libc 中的一个错误,他们使用 8 位无符号整数类型将 fd 存储在 FILE 结构中。显然他们并没有以向后兼容的名义很快地改变它(如果一个程序由于某种原因依赖于 FILE 结构的实现细节)。这应该是 Linux 或任何其他非 solaris *nix 上的问题。您引用的文章建议了合理的解决方法,因此您应该使用这些方法。

至于“什么是 64 位可执行文件”,它只是针对 64 位指令集编译的二进制文件。有些架构支持两者,有些则不支持。(例如 x86-64 操作系统通常允许 32 位进程以实现向后兼容性)。

于 2008-11-23T04:14:07.920 回答
1

要检查目标文件(可执行文件)是否为 64 位,请使用 file 命令(至少在 Linux 上)。

例如:

$ file `which ls`
/bin/ls: ELF 64-bit LSB executable, x86-64, version 1 (SYSV), for GNU/Linux 2.6.9, dynamically linked (uses shared libs), stripped

$ file my-32bit-exe
my-32bit-exe: ELF 32-bit LSB executable, Intel 80386, version 1 (SYSV), dynamically linked (uses shared libs), corrupted section header size

(不要介意“损坏的节标题大小”——exe 被手动修改以减小文件大小)。

ulimit 可以在 Linux 上使用(参见ulimit(1)ulimit(3))。

于 2008-11-23T04:09:29.257 回答
1

在 Solaris 上,您可以使用以下任一方式构建 64 位程序:

cc -xarch=v9 ...

或者:

gcc -m64 ...

正如 Evan 所说,32 位 Solaris 的基本问题是向后二进制兼容性和用于保存 fd 的 8 位整数。

我刚刚在 Solaris 10 for SPARC 上尝试了以下代码:

#include <stdio.h>

int main(void)
{
    size_t i;
    for (i = 0; i < 300; i++)
    {
        FILE *fp = fopen("/dev/null", "a");
        if (fp == 0)
        {
            printf("Failed on %zu\n", i);
            return(1);
        }
    }
    printf("Succeeded to %zu\n", i);
    return(0);
}

编译为:

cc -xarch=v9 -o xxx xxx.c

它给了我“在 253 上失败”。(这是测试代码:我知道它会丢弃 252 个指针。)这支持您的论点,即简单的 64 位构建。然而,还有另一个因素在起作用——资源限制。

$ ulimit -n
256
$

因此,通过以下方式增加默认限制:

$ ulimit -n 400
$ ulimit -n
400
$ ./xxx
Succeeded to 300
$

试试那个...

于 2008-11-23T05:52:09.767 回答
0

就像 Evan Teran 提到的,solaris libc 对 FILE 有这个“奇怪”的限制,它只能处理 256 以下的文件句柄。

这与您可以使用 ulimit 设置的限制无关。您可以通过以下方式设置此限制:

#include <sys/resource.h>

struct rlimit rl;
getrlimit(RLIMIT_NOFILE,&rl);
rl.rlim_cur = 1024; /* change it to 1024 - note has to be < than rl.rlim_max */
setrlimit(RLIMIT_NOFILE,&rl);

现在,我也将停止使用 FILE* 并使用 open 而不是 fopen 等。对于您真正需要使用 FILE* 的情况,在我工作的几个项目中,在程序开始时,几个文件描述符被“保留” " 通过进行套接字调用,我们有一个小型库来使用这些获取 FILE*,方法是关闭其中一个套接字,然后立即执行 fopen,它将使用刚刚关闭的 fd。当然,还需要使用 fclose 的特殊功能关闭 FILE*,然后使用套接字立即获取 fd ;-)

于 2008-11-23T14:50:23.283 回答
0

最后我得到了解决方案。我对代码进行了两项更改以使其正常工作

1) 如上面 njsf 所建议的那样

2) 打开带有“F”标志的文件,如下 FILE *fp = fopen("/dev/null", "wF");

非常感谢。DL库马尔

于 2008-11-24T10:00:41.603 回答