5

我很好奇在 Linux/OSX/FreeBSD 上 write() 和 read() 可以处理什么样的缓冲区大小,所以我开始玩弄下面这样的愚蠢程序:

#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

int main( void ) {
    size_t s = 8*1024*1024 - 16*1024;
    while( 1 ) {
        s += 1024;
        int f = open( "test.txt", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR );
        char mem[s];
        size_t written = write( f, &mem[0], s );
        close( f );
        printf( "(%ld) %lu\n", sizeof(size_t), written );
    }
    return 0;
}

这让我可以测试在出现段错误之前我能达到的“8MB 障碍”有多接近。在 8MB 左右的某个地方,我的程序死掉了,这是一个示例输出:

(8) 8373248
(8) 8374272
(8) 8375296
(8) 8376320
(8) 8377344
(8) 8378368
(8) 8379392
(8) 8380416
(8) 8381440
(8) 8382464
Segmentation fault: 11

这在 OSX 和 Linux 上是一样的,但是我的 FreeBSD VM 不仅在运行这个测试时要快得多,而且还可以继续运行很多方法!我已经成功地测试了它高达 511MB,这只是一个可笑的数据量在一次调用中写入。

是什么导致 write() 调用段错误,我如何才能在一次调用中计算出我可能 write() 的最大数量,而不会像我现在正在做的那样做一些荒谬的事情?

(注意,这三个操作系统都是 64 位的,OSX 10.7.3,Ubuntu 11.10,FreeBSD 9.0)

4

1 回答 1

5

故障不在 内,write()而是堆栈溢出。试试这个:

#include <stdlib.h>
#include <unistd.h>
#include <fcntl.h>
#include <stdio.h>
#include <string.h>
#include <sys/stat.h>

int main( void )
{
    void *mem;
    size_t s = 512*1024*1024 - 16*1024;
    while( 1 )
    {
        s += 1024;
        int f = open( "test.txt", O_CREAT | O_WRONLY | O_TRUNC, S_IRUSR | S_IWUSR | S_IXUSR );
        mem = malloc(s);
        size_t written = write( f, mem, s );
        free(mem);
        close( f );
        printf( "(%ld) %lu\n", sizeof(size_t), written );
    }
    return 0;
}
于 2012-04-20T08:07:33.877 回答