Мне было любопытно, с какими размерами буфера write() и read() могут работать в Linux/OSX/FreeBSD, поэтому я начал экспериментировать со следующими тупыми программами:
#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;
}
Это позволило меня, чтобы проверить, насколько близко к кажущемуся «барьеру в 8 МБ» я мог бы подойти, прежде чем segfaulting. Где-то на отметке 8 МБ моя программа умирает, вот пример вывода:
(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 не только намного быстрее выполняет этот тест, но и может продолжаться довольно долго. ! Я успешно протестировал его до 511 МБ, что является просто смехотворным объемом данных для записи за один вызов.
Что делает вызов write() segfault, и как я могу вычислить максимальную сумму, которую я могу написать() за один вызов, не делая при этом чего-то нелепого, как я делаю сейчас?
(Примечание: все три операционные системы 64-разрядные, OSX 10.7.3, Ubuntu 11.10, FreeBSD 9.0)