Читаем Linux API. Исчерпывающее руководство полностью

$ ./t_nanosleep 10 0 Сон на протяжении 10 секунд

Нажимаем Ctrl+C

Slept for: 1.853428 secs

Remaining: 8.146617000

Нажимаем Ctrl+C

Slept for: 4.370860 secs

Remaining: 5.629800000

Нажимаем Ctrl+C

Slept for: 6.193325 secs

Remaining: 3.807758000

Slept for: 10.008150 secs

Sleep complete

Функция nanosleep() позволяет указывать продолжительность сна в наносекундах, одна ее реальная точность ограничена программными часами (см. раздел 10.6). Если указать интервал, который не является кратным программным часам, он будет округлен в большую сторону.

Как отмечалось ранее, в системах, поддерживающих высокоточные таймеры, точность сна может быть намного лучше, чем у программных часов.

Наличие округления означает, что, если сигналы принимают с высокой частотой, у нас могут возникнуть проблемы с подходом, который используется в программе из листинга 23.3. Дело в том, что при каждом повторном запуске nanosleep() будет накапливаться отклонение, связанное с округлением, так как вероятность того, что итоговое значение remain окажется кратным наименьшему интервалу программных часов, довольно низкая. Следовательно, каждый следующий вызов nanosleep() будет останавливать выполнение на более продолжительное время, чем указано в значении remain предыдущего вызова. В случае если сигналы доставляются с высокой частотой (то есть чаще, чем обновляются программные часы), процесс может никогда не выйти из состояния сна. В Linux 2.6 и выше эту проблему можно обойти с помощью вызова clock_nanosleep() и параметра TIMER_ABSTIME, которые будут рассмотрены в подразделе 23.5.4.


Листинг 23.3. Использование функции nanosleep()

timers/t_nanosleep.c

#define _POSIX_C_SOURCE 199309

#include

#include

#include

#include "tlpi_hdr.h"


static void

sigintHandler(int sig)

{

return; /* Просто прерываем nanosleep() */

}


int

main(int argc, char *argv[])

{

struct timeval start, finish;

struct timespec request, remain;

struct sigaction sa;

int s;


if (argc!= 3 || strcmp(argv[1], "-help") == 0)

usageErr("%s secs nanosecs\n", argv[0]);

request.tv_sec = getLong(argv[1], 0, "secs");

request.tv_nsec = getLong(argv[2], 0, "nanosecs");


/* Позволяем обработчику SIGINT прерывать nanosleep() */


sigemptyset(&sa.sa_mask);

sa.sa_flags = 0;

sa.sa_handler = sigintHandler;

if (sigaction(SIGINT, &sa, NULL) == –1)

errExit("sigaction");


if (gettimeofday(&start, NULL) == –1)

errExit("gettimeofday");


for (;;) {

s = nanosleep(&request, &remain);

if (s == –1 && errno!= EINTR)

errExit("nanosleep");


if (gettimeofday(&finish, NULL) == –1)

errExit("gettimeofday");

printf("Slept for: %9.6f secs\n", finish.tv_sec — start.tv_sec +

(finish.tv_usec — start.tv_usec) / 1000000.0);


if (s == 0)

break; /* Вызов nanosleep() завершен */


printf("Remaining: %2ld.%09ld\n", (long) remain.tv_sec, remain.tv_nsec);

request = remain; /* Следующий переход в режим сна будет

длиться оставшееся время */

}


printf("Sleep complete\n");

exit(EXIT_SUCCESS);

}

timers/t_nanosleep.c


23.5. Часы стандарта POSIX


POSIX-часы (изначально разработанные для стандарта POSIX.1b) предоставляют программный интерфейс для доступа к часам, которые измеряют время в наносекундах. Для представления такого времени используется та же структура timespec, которую мы применяли в подразделе 23.4.2 в вызове nanosleep().

В Linux программы, которые работают с этим интерфейсом, должны быть скомпилированы с параметром — lrt, иначе их нельзя будет скомпоновать с библиотекой реального времени librt.

Главными системными вызовами программного интерфейса POSIX-часов являются clock_gettime(), который возвращает текущее значение часов, clock_getres(), позволяющий определить их точность, и clock_settime(), который обновляет часы.


23.5.1. Получение текущего значения часов: вызов clock_gettime()

Системный вызов clock_gettime() возвращает время в соответствии с часами, указанными в аргументе clockid.

#define _POSIX_C_SOURCE 199309

#include


int clock_gettime(clockid_t clockid, struct timespec *tp);

int clock_getres(clockid_t clockid, struct timespec *res);

Оба вызова возвращают 0 при успешном завершении или –1, если случилась ошибка

На значение времени, возвращаемое внутри структуры timespec, указывает аргумент tp. И хотя структура timespec поддерживает наносекунды, значение, возвращенное вызовом clock_gettime(), может оказаться менее точным. Системный вызов clock_getres() возвращает указатель на структуру timespec (аргумент clockid), в которой содержится точность часов.

Тип данных clockid_t предусмотрен стандартом SUSv3 для представления идентификатора часов. Значения, которые можно указывать в аргументе clockid, перечислены в первом столбце табл. 23.1.


Таблица 23.1. Типы часов стандарта POSIX.1b

Идентификатор часов — Описание

Перейти на страницу:

Похожие книги

C++ Primer Plus
C++ Primer Plus

C++ Primer Plus is a carefully crafted, complete tutorial on one of the most significant and widely used programming languages today. An accessible and easy-to-use self-study guide, this book is appropriate for both serious students of programming as well as developers already proficient in other languages.The sixth edition of C++ Primer Plus has been updated and expanded to cover the latest developments in C++, including a detailed look at the new C++11 standard.Author and educator Stephen Prata has created an introduction to C++ that is instructive, clear, and insightful. Fundamental programming concepts are explained along with details of the C++ language. Many short, practical examples illustrate just one or two concepts at a time, encouraging readers to master new topics by immediately putting them to use.Review questions and programming exercises at the end of each chapter help readers zero in on the most critical information and digest the most difficult concepts.In C++ Primer Plus, you'll find depth, breadth, and a variety of teaching techniques and tools to enhance your learning:• A new detailed chapter on the changes and additional capabilities introduced in the C++11 standard• Complete, integrated discussion of both basic C language and additional C++ features• Clear guidance about when and why to use a feature• Hands-on learning with concise and simple examples that develop your understanding a concept or two at a time• Hundreds of practical sample programs• Review questions and programming exercises at the end of each chapter to test your understanding• Coverage of generic C++ gives you the greatest possible flexibility• Teaches the ISO standard, including discussions of templates, the Standard Template Library, the string class, exceptions, RTTI, and namespaces

Стивен Прата

Программирование, программы, базы данных
1С: Бухгалтерия 8 с нуля
1С: Бухгалтерия 8 с нуля

Книга содержит полное описание приемов и методов работы с программой 1С:Бухгалтерия 8. Рассматривается автоматизация всех основных участков бухгалтерии: учет наличных и безналичных денежных средств, основных средств и НМА, прихода и расхода товарно-материальных ценностей, зарплаты, производства. Описано, как вводить исходные данные, заполнять справочники и каталоги, работать с первичными документами, проводить их по учету, формировать разнообразные отчеты, выводить данные на печать, настраивать программу и использовать ее сервисные функции. Каждый урок содержит подробное описание рассматриваемой темы с детальным разбором и иллюстрированием всех этапов.Для широкого круга пользователей.

Алексей Анатольевич Гладкий

Программирование, программы, базы данных / Программное обеспечение / Бухучет и аудит / Финансы и бизнес / Книги по IT / Словари и Энциклопедии
C# 4.0: полное руководство
C# 4.0: полное руководство

В этом полном руководстве по C# 4.0 - языку программирования, разработанному специально для среды .NET, - детально рассмотрены все основные средства языка: типы данных, операторы, управляющие операторы, классы, интерфейсы, методы, делегаты, индексаторы, события, указатели, обобщения, коллекции, основные библиотеки классов, средства многопоточного программирования и директивы препроцессора. Подробно описаны новые возможности C#, в том числе PLINQ, библиотека TPL, динамический тип данных, а также именованные и необязательные аргументы. Это справочное пособие снабжено массой полезных советов авторитетного автора и сотнями примеров программ с комментариями, благодаря которым они становятся понятными любому читателю независимо от уровня его подготовки. Книга рассчитана на широкий круг читателей, интересующихся программированием на C#.Введите сюда краткую аннотацию

Герберт Шилдт

Программирование, программы, базы данных