simbolo sacar restar que promedio programa porcentajes porcentaje por lenguaje con como ciento calificaciones calcule calcular arreglos c++ c linux filesystems

c++ - sacar - Convertir statvfs a porcentaje libre correctamente



restar porcentaje en c++ (5)

En su Edición # 2, el cálculo de% de uso debe actualizarse para que coincida con la salida de df:

100.0 * (double) (vfs.f_blocks - vfs.f_bfree) / (double) (vfs.f_blocks - vfs.f_bfree + vfs.f_bavail)

Razonamiento:
Utilizado = f_blocks - f_bfree
Avail = f_bavail
df% = Usado / (Usado + Disponibilidad)

Tengo un programa de prueba terriblemente sencillo que imprime los siguientes números.

es decir

int main(int argc, char* argv[]) struct statvfs vfs; statvfs(argv[1], &vfs); printf("f_bsize (block size): %lu/n" "f_frsize (fragment size): %lu/n" "f_blocks (size of fs in f_frsize units): %lu/n" "f_bfree (free blocks): %lu/n" "f_bavail free blocks for unprivileged users): %lu/n" "f_files (inodes): %lu/n" "f_ffree (free inodes): %lu/n" "f_favail (free inodes for unprivileged users): %lu/n" "f_fsid (file system ID): %lu/n" "f_flag (mount flags): %lu/n" "f_namemax (maximum filename length)%lu/n", vfs.f_bsize, vfs.f_frsize, vfs.f_blocks, vfs.f_bfree, vfs.f_bavail, vfs.f_files, vfs.f_ffree, vfs.f_favail, vfs.f_fsid, vfs.f_flag, vfs.f_namemax); return 0; }

Imprime:

f_bsize (block size): 4096 f_frsize (fragment size): 4096 f_blocks (size of fs in f_frsize units): 10534466 f_bfree (free blocks): 6994546 f_bavail free blocks for unprivileged users): 6459417 f_files (inodes): 2678784 f_ffree (free inodes): 2402069 f_favail (free inodes for unprivileged users): 2402069 f_fsid (file system ID): 12719298601114463092 f_flag (mount flags): 4096 f_namemax (maximum filename length)255

df imprime para la raíz fs:

Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda5 42137864 14159676 25837672 36% /

Pero aquí es donde estoy confundido.

25837672 + 14159676! = 42137846 (en realidad 39997348)

Por lo tanto, si tuviera que hacer el cálculo 14159676/42137864 * 100 obtendré el 33%, no el 36% como impresiones df.

Pero si me calculo

14159676/39997348 * 100 Tengo 35%.

¿Por qué todas las discrepancias y dónde está df obteniendo el número 42137864? ¿Está relacionado con alguna conversión a bloques de 1k frente al tamaño real del bloque del sistema que es 4k?

Esto se integrará en mi aplicación de almacenamiento en caché para indicarme cuándo el disco está en algún umbral ... por ejemplo, 90% antes de que comience a liberar bloques de tamaño fijo con un tamaño de 2 ^ n. Entonces, lo que busco es una función que me dé un% de precisión razonable.

EDIT: Ahora puedo hacer coincidir lo que df imprime. Excepto por el% utilizado. Nos hace preguntarnos qué tan preciso es todo esto. ¿Cuál es el tamaño del fragmento?

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024; unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024; unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024; printf("Total: %luK/n", total); printf("Available: %luK/n", available); printf("Used: %luK/n", total - free);

EDIT2:

unsigned long total = vfs.f_blocks * vfs.f_frsize / 1024; unsigned long available = vfs.f_bavail * vfs.f_frsize / 1024; unsigned long free = vfs.f_bfree * vfs.f_frsize / 1024; unsigned long used = total - free; printf("Total: %luK/n", total); printf("Available: %luK/n", available); printf("Used: %luK/n", used); printf("Free: %luK/n", free); // Calculate % used based on f_bavail not f_bfree. This is still giving out a different answer to df??? printf("Use%%: %f%%/n", (vfs.f_blocks - vfs.f_bavail) / (double)(vfs.f_blocks) * 100.0); f_bsize (block size): 4096 f_frsize (fragment size): 4096 f_blocks (size of fs in f_frsize units): 10534466 f_bfree (free blocks): 6994182 f_bavail (free blocks for unprivileged users): 6459053 f_files (inodes): 2678784 f_ffree (free inodes): 2402056 f_favail (free inodes for unprivileged users): 2402056 f_fsid (file system ID): 12719298601114463092 f_flag (mount flags): 4096 f_namemax (maximum filename length)255 Total: 42137864K Available: 25836212K Used: 14161136K Free: 27976728K Use%: 38.686470% matth@kubuntu:~/dev$ df Filesystem 1K-blocks Used Available Use% Mounted on /dev/sda5 42137864 14161136 25836212 36% /

Obtengo el 38%, no el 36. Si se calcula por f_bfree, obtengo el 33%. ¿Está df equivocado o esto nunca va a ser preciso? Si este es el caso, entonces quiero apoyarme en ser conservador.


Esto es lo más cercano que he encontrado para hacer coincidir la salida de df -h para el porcentaje utilizado:

const uint GB = (1024 * 1024) * 1024; struct statvfs buffer; int ret = statvfs(diskMountPoint.c_str(), &buffer); const double total = ceil((double)(buffer.f_blocks * buffer.f_frsize) / GB); const double available = ceil((double)(buffer.f_bfree * buffer.f_frsize) / GB); const double used = total - available; const double usedPercentage = ceil((double)(used / total) * (double)100); return usedPercentage;



Los datos de df pueden estar basados ​​en f_bavail , no en f_bfree . Puede que le resulte útil consultar el código fuente de df para ver cómo hace las cosas. Tiene una serie de casos de borde con los que debe lidiar (por ejemplo, cuando el espacio utilizado excede la cantidad de espacio disponible para usuarios no root), pero el código relevante para el caso normal está aquí:

uintmax_t u100 = used * 100; uintmax_t nonroot_total = used + available; pct = u100 / nonroot_total + (u100 % nonroot_total != 0);

En otras palabras, 100 * used / (used + available) , redondeado hacia arriba. Al conectar los valores de su salida de df se obtienen 100 * 14159676 / (14159676 + 25837672) = 35.4015371 , que se redondearon al 36%, tal como se calculó df .


Parece que me confundo cada vez que trato con este problema. Espero que el siguiente código C sea útil para alguien que busca un porcentaje del espacio utilizado:

/* * It is helpful to use a picture to aid the calculation of disk space. * * |<--------------------- f_blocks ---------------------------->| * |<---------------- f_bfree ------------------>| * * --------------------------------------------------------------- * | USED | f_bavail | Reserved for root | * --------------------------------------------------------------- * * We want the percentage of used blocks vs. all the * non-reserved blocks: USED / (USED + f_bavail) */ fsblkcnt_t used = fs_stats.f_blocks - fs_stats.f_bfree; double fraction_used = (double) used / ((double) used + (double) fs_stats.f_bavail); uint8_t percent_used = (uint8_t) ((fraction_used * 100.0) + 0.5); // Add 0.5 for rounding