const char* journal_filename = "journal.log";
void write_journal_entry(char* entry) {
int fd =
open(journal_filename,
O_WRONLY | O_CREAT | O_APPEND, 0660);
write(fd, entry, strlen(entry));
write(fd, "\n", 1);
fsync(fd);
close(fd);
}
Аналогичное действие выполняет другой системный вызов: fdatasync()
fsync()
гарантирует, что дата модификации файла будет обновлена, то функция fdatasync()
этого не делает, а лишь гарантирует запись данных. В принципе это означает, что функция fdatasync()
способна выполняться быстрее, чем fsync()
, так как ей требуется выполнить одну операцию записи на диск, а не две. Но в настоящее время в Linux обе функции работают одинаково, обновляя дату модификации.Файл можно также открыть в режиме
open()
следует указать флаг O_SYNC
.8.5. Функции getrlimit() и setrlimit(): лимиты ресурсов
Функции getrlimit()
setrlimit()
позволяют процессу определять и задавать лимиты использования системных ресурсов. Аналогичные действия выполняет команда ulimit
, которая ограничивает доступ запускаемых пользователем программ к ресурсам.У каждого ресурса есть два лимита:
Обе функции принимают два аргумента: код, задающий тип ограничения, и указатель на структуру типа rlimit
getrlimit()
заполняет поля этой структуры, тогда как функция setrlimit()
проверяет их и соответствующим образом меняет лимит. У структуры rlimit
два поля: в поле rlim_cur
содержится значение нежесткого лимита, а в поле rlim_max
— значение жесткого лимита.Ниже перечислены коды наиболее полезных лимитов, допускающих возможность изменения.
■ RLIMIT_CPU
SIGXCPU
.■ RLIMIT_DATA
■ RLIMIT_NPROC
fork()
, а лимит уже исчерпал, функция завершается ошибкой.■ RLIMIT_NOFILE
Программа, приведенная в листинге 8.4, задает односекундный лимит использования центрального процессора, после чего переходит в бесконечный цикл. Как только программа превышает установленный ею же лимит, ОС Linux уничтожает ее.
#include
#include
#include
int main() {
struct rlimit rl;
/* Определяем текущие лимиты. */
getrlimit(RLIMIT_CPU, &rl);
/* Ограничиваем время доступа к процессору
одной секундой. */
rl.rlim_cur = 1;
setrlimit(RLIMIT_CPU, &rl);
/* Переходим в бесконечный цикл. */
while(1);
return 0;
}
Когда программа завершается по сигналу SIGXCPU
% ./limit_cpu
CPU time limit exceeded
8.6. Функция getrusage(): статистика процессов
Функция getrusage()
RUSAGE_SELF
, процесс получит информацию о самом себе. Если же первым аргументом является константа RUSAGE_CHILDREN
, будет выдана информация обо всех его завершившихся дочерних процессах. Второй аргумент — это указатель на структуру типа rusage
, в которую заносятся статистические данные.Перечислим наиболее интересные поля этой структуры.
■ ru_utime
timeval
, в которой указано, сколько пользовательского времени (в секундах) ушло на выполнение процесса. Это время, затраченное центральным процессором на выполнение программного кода, а не системных вызовов.