IBM®
Перейти к тексту
    в России и странах СНГ [изменить]    Условия использования
 
 
   
    Главная страница    Продукты    Услуги и решения    Поддержка и загрузка    Мой профиль    
Перейти к тексту

developerWorks Россия  >  Linux | Open source  >

Разработка программного обеспечения для телефонов OpenMoko под управлением Linux

Открытая бесплатная платформа для мобильных коммуникаций

developerWorks
На предыдущую страницуСтраница 8 из 13 На предыдущую страницу

Опции документа

Обсудить

Исходные тексты примера


Выскажите мнение об этом учебном пособии

Помогите нам улучшить содержание


Добавление возможностей

Что дальше?

Теперь, когда у нас есть базовый интерфейс, позволяющий выполнять считывание данных, следующим вопросом будет - какие ещё данные могут быть полезны? Еще один доступный параметр - это свободное дисковое пространство. Узнать его можно несколькими способами.

Определение дискового пространства

Узнать размер свободного дискового пространства можно с помощью системного вызова statfs() . Эта функция возвращает строку, содержащую текущую статистику использования дискового пространства:


Листинг 13. Определение свободного дискового пространства
                    
static char *
diskfree(void)
{
   static char capacity[16];
   struct statfs buf;
   if (statfs("/", &buf) < 0) {
      strcpy(capacity, "unavailable");
   } else {
      double used = 1.0 - ((double) buf.f_bavail / buf.f_blocks);
      sprintf(capacity, "%.1f%%", (used * 100));
   }
   return capacity;
}

Системный вызов statfs(), подобно stat(), возвращает информацию об указанном пути, за тем исключением, что он показывает не файловую статистику, а статистику файловой системы. В качестве некоторой странности, хотя все привыкли выражать занимаемое пространство в процентах, statfs() сообщает только доступный на данный момент объём. Этот код рассчитывает используемый объём (в диапазоне от 0 до 1) и преобразует его в проценты. Обратите внимание на то, что для проверки ошибок необходимо добавление заголовка <string.h> к strcpy().

Добавление информации

Теперь процедура нам хорошо знакома:


Листинг 14. Добавление меток
                    
/* disk space */
label = gtk_label_new("Disk usage:");
gtk_table_attach(GTK_TABLE(table), label,
    0, 1,
    1, 2,
    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
    0, 0);

label = gtk_label_new(diskfree());
gtk_table_attach(GTK_TABLE(table), label,
    1, 3,
    1, 2,
    GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
    0, 0);

На самом деле подобные вещи выглядят как шаблоны, которые можно использовать. Фактически здесь изменяются только номер строки таблицы и две строковые переменные.

Время реорганизации кода

Немного обобщая, мы можем создать функцию, которая выводит один из этих параметров в таблицу. Суть эффективного программирования лежит в творчестве; я творчески назвал функцию label_in_table(). Какие аргументы нужны для неё? Ей нужна таблица, строка, описательная метка (слева) и текст, который необходимо вывести (справа). Итак:


Листинг 15. Извлеченные параметры
                    
static void
label_in_table(GtkWidget *table, int row, char *name, char *value)
{
   GtkWidget *label;

   label = gtk_label_new(name);
   gtk_table_attach(GTK_TABLE(table), label,
      0, 1,
      row, row + 1,
      GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
      0, 0);

   label = gtk_label_new(value);
   gtk_table_attach(GTK_TABLE(table), label,
      1, 3,
      row, row + 1,
      GTK_EXPAND | GTK_FILL, GTK_EXPAND | GTK_FILL,
      0, 0);
}

Вызов label_in_table()

Давайте теперь упростим основную функцию. Теперь это намного проще, чем раньше:


Листинг 16. Исправленный и упрощённый код
                    
/* uname */
uname(&u);
label_in_table(table, 0, "Kernel version:", u.release);

/* disk space */
label_in_table(table, 1, "Disk usage:", diskfree());

Этот пример указывает на несколько моментов. Первый состоит в том, что table может быть кандидатом в глобальные переменные; в конце концов это единственная такая таблица. Другой момент - вы можете подумать о том, что может иметь смысл использование статической или глобальной переменной для отслеживания номеров строк—и это так, за исключением того, что в будущем может понадобиться замена содержимого существующей строки, поэтому хорошо бы иметь возможность указания целевой строки.

Информация о памяти

На следующем шаге мы займемся информацией о памяти. Отправной точкой для этого служит вызов sysinfo(). Поскольку вызов sysinfo() возвращает несколько полезных элементов информации, способ, которым код будет обращаться с ним, будет посложнее—но только слегка. Подобно uname() и statfs(), sysinfo() извлекает данные в структуру (struct sysinfo).

Из неё достаточно просто извлекается значение величины использованной памяти.


Листинг 17. Определение использования памяти
                    
sprintf(buffer, "%.1f%%",
    (100 * (1.0 - ((double) si.freeram / si.totalram))));
label_in_table(table, 2, "Memory usage:", buffer);

Загрузка системы

Получить значение загрузки системы очень просто; средние значения нагрузки за одну, пять и пятнадцать минут хранятся в struct sysinfo, как unsigned long. Однако традиционно средняя нагрузка показывается пользователю как средняя длина очереди задач, как правило, в виде числа с плавающей запятой. Средняя нагрузка 1,00 показывает, что система находится на нижнем пределе полной загрузки. Итак, как преобразовать значения unsigned long в более привычные? Это, хотя и не очень понятно, изложено на странице man sysinfo(). Секрет заключается в макросе SI_LOAD_SHIFT, в котором хранится коэффициент пересчёта; фактически unsigned long трактуются как дробные значения с фиксированной запятой. Чаще всего SI_LOAD_SHIFT равно 16, то означает, что средняя нагрузка 1,0 представляется как 65 536.

Этот тип расчетов вызывает функцию helper:


Листинг 18. Получение средней нагрузки
                    
static double
scaled_load(long int unscaled) {
        return (double) unscaled / (1 << SI_LOAD_SHIFT);
}

Полученные значения могут выводиться на печать так же, как остальные – на экран:


Листинг 19. Отобрвжение средней нагрузки
                    
sprintf(buffer, "%.2f %.2f %.2f",
    scaled_load(si.loads[0]), scaled_load(si.loads[1]),
    scaled_load(si.loads[2]));
label_in_table(table, 3, "Load:", buffer);

На этом пока все.

Пора посмотреть на готовую программу Вот экран программы:


Рисунок 2. Апплет системной информации
Апплет системной информации

На предыдущую страницуСтраница 8 из 13 На предыдущую страницу
    IBM в России Конфиденциальность Контакты