2010-01-16 11 views
7

¿Dónde puedo leer sobre sbrk() con algún detalle?¿Cómo funciona sbrk() en C++?

¿Cómo funciona exactamente?

¿En qué situaciones quisiera usar sbrk() en lugar de los engorrosos malloc() y new()?

por cierto, ¿cuál es la expansión de sbrk()?

Respuesta

8

Eche un vistazo a the specification for brk/sbrk.

La llamada básicamente le pide al sistema operativo que asigne más memoria para la aplicación al incrementar el "valor de corte" anterior en cierta cantidad. Esta cantidad (el primer parámetro) es la cantidad de memoria extra que obtiene su aplicación.

La mayoría de las implementaciones rudimentarias de malloc se basan en la llamada del sistema sbrk para obtener bloques de memoria que se dividen y rastrean. La función mmap generalmente se acepta como una mejor opción (por lo que los mallocs como dlmalloc son compatibles con un #ifdef).

En cuanto a "cómo funciona", un sbrk en su nivel más simple podría ser algo como esto:

uintptr_t current_break; // Some global variable for your application. 
         // This would probably be properly tracked by the OS for the process 
void *sbrk(intptr_t incr) 
{ 
    uintptr_t old_break = current_break; 
    current_break += incr; 
    return (void*) old_break; 
} 

sistemas operativos modernos harían mucho más, como el mapa páginas en el espacio de direcciones y agregue información de seguimiento para cada bloque de memoria asignado.

+0

Tenga en cuenta que las funciones están marcadas como 'LEGACY' en la referencia; si va a la especificación SUS actual (http://www.opengroup.org/onlinepubs/9699919799/toc.htm), ellos (brk, sbrk) no están presentes. –

+0

Buen punto: usar tales funciones bien puede causar problemas de portabilidad si una implementación decide no importar la compatibilidad con versiones anteriores. –

4

sbrk es bastante obsoleto, en estos días utilizaría mmap para asignar algunas páginas fuera de/dev/zero. Ciertamente no es algo que uses en lugar de malloc y tus amigos, es más una forma de implementarlos. Además, por supuesto, existe solo en sistemas operativos basados ​​en posix que se preocupan por la compatibilidad con versiones anteriores del código antiguo.

Si encuentra que Malloc y New son demasiado engorrosos, debe buscar en la recolección de basura en su lugar ... pero tenga cuidado, existe un costo de rendimiento potencial, por lo que debe comprender lo que está haciendo.

0

Esto depende de lo que quiere decir con que malloc es "engorroso". sbrk por lo general ya no se usa directamente, a menos que esté implementando su propio asignador de memoria: IE, el operador reemplaza "nuevo". Incluso entonces posiblemente usaría malloc para darme mi memoria inicial.

Si desea ver cómo implementar malloc() en la parte superior de sbrk(), consulte http://web.ics.purdue.edu/~cs354/labs/lab6/, que es un ejercicio que se está llevando a cabo.

En un sistema moderno no debe tocar esta interfaz, sin embargo. Ya que llama malloc y nuevo engorroso, sospecho que no tiene toda la experiencia necesaria para usar de forma segura y adecuada sbrk para su código.

1

Usted nunca desea usar sbrk en lugar de malloc o free. No es portátil y, por lo general, solo lo utilizan los implementadores de la biblioteca C estándar o en los casos en que no está disponible.Es descrito bastante bien en su man page:

Descripción

brk() establece el final del segmento de datos en el valor especificado por end_data_segment, cuando ese valor es razonable, el sistema hace tiene memoria suficiente y el proceso no supera su tamaño máximo de datos (consulte setrlimit (2)).

sbrk() incrementa los datos del programa espacio por bytes de incremento. sbrk() no es una llamada al sistema, solo es una envoltura de la biblioteca C . Llamar a sbrk() con un incremento de de 0 se puede usar para encontrar la ubicación actual del salto de programa.

Valor de retorno

En caso de éxito, brk() devuelve cero, y sbrk() devuelve un puntero a el inicio de la nueva zona. En caso de error, se devuelve -1 y errno se establece en ENOMEM.

Por último, malloc y free no son engorrosos - que son la forma estándar de asignar y liberar memoria en C Incluso si se desea implementar su propio gestor de memoria, lo mejor es utilizar sólo malloc y free como base - un enfoque común es asignar una gran parte a la vez con malloc y proporcionar la asignación de memoria de ella (esto es lo que suballocators, o piscinas, generalmente implementan)


Re el origen del nombre sbrk (o su primo brk), puede h Tiene algo que ver con el hecho de que el final del montón está marcado por un puntero conocido como "ruptura". El montón comienza justo después de los segmentos de BSS y generalmente crece hacia la pila.

1

Ha marcado este C++, entonces, ¿por qué usaría 'engrosome' malloc() en lugar de nuevo? No estoy seguro de qué es engorroso sobre Malloc en cualquier caso; Internamente, tal vez sea así, pero ¿por qué te importa? Y si le importó (por razones de determinismo, por ejemplo), podría asignar un grupo grande e implementar su propio asignador para ese grupo. En C++, por supuesto, puede sobrecargar al nuevo operador para hacer eso.

sbrk se utiliza para pegar la biblioteca C a la administración de memoria del sistema operativo subyacente del sistema. Así que haga llamadas al sistema operativo en lugar de usar sbrk(). En cuanto a cómo funciona, eso depende del sistema. Si, por ejemplo, está utilizando la biblioteca Newlib C (comúnmente utilizada en sistemas embebidos 'bare-metal' con el compilador GNU), tiene que implement sbrk yourself, entonces cómo funciona en esas circunstancias depende de usted siempre que logre su requerimiento comportamiento de extender el montón o fallar.

Como se puede ver en el enlace, no hace mucho, y sería extremadamente engorroso de usar directamente - es probable que terminaría en marcha envolviéndolo en toda la funcionalidad que malloc y nuevos proporcionan en cualquier caso.