Ответ 1
Технически это не должно иметь никакого эффекта. Но вы должны помнить, что переданное значение используется как минимум, а не абсолютное, поэтому система может использовать наименьший возможный интервал.
Документация для usleep утверждает, что вызов usleep(0)
не влияет. Тем не менее, в моей системе (RHEL 5.2), выполняющей небольшие фрагменты кода на С++ ниже, я обнаружил, что на самом деле он имеет тот же эффект, что и usleep(1)
. Можно ли ожидать этого, и если да, то почему существует несоответствие между документацией и тем, что я вижу в реальной жизни?
Иллюстрация A
код:
#include <unistd.h>
int main()
{
for( int i = 0; i < 10000; i++ )
{
usleep(1);
}
}
Вывод:
$ time ./test
real 0m10.124s
user 0m0.001s
sys 0m0.000s
Иллюстрация B
код:
#include <unistd.h>
int main()
{
for( int i = 0; i < 10000; i++ )
{
usleep(1);
usleep(0);
}
}
Вывод:
$ time ./test
real 0m20.770s
user 0m0.002s
sys 0m0.001s
Технически это не должно иметь никакого эффекта. Но вы должны помнить, что переданное значение используется как минимум, а не абсолютное, поэтому система может использовать наименьший возможный интервал.
Я просто хотел указать на команду времени, используемую здесь. Вы должны использовать /usr/bin/time
вместо команды time
, если вы хотите проверить свою память программы, cpu, time stat. Когда вы вызываете время без полного пути, вызывается встроенная команда времени. Посмотрите на разницу.
# time -v ./a.out
-bash: -v: command not found
real 0m0.001s
user 0m0.000s
sys 0m0.001s
# /usr/bin/time -v ./a.out
Command being timed: "./a.out"
User time (seconds): 0.00
System time (seconds): 0.00
Percent of CPU this job got: 0%
Elapsed (wall clock) time (h:mm:ss or m:ss): 0:10.87
Average shared text size (kbytes): 0
Average unshared data size (kbytes): 0
Average stack size (kbytes): 0
Average total size (kbytes): 0
Maximum resident set size (kbytes): 0
Average resident set size (kbytes): 0
Major (requiring I/O) page faults: 0
Minor (reclaiming a frame) page faults: 220
Voluntary context switches: 10001
Involuntary context switches: 1
Swaps: 0
File system inputs: 0
File system outputs: 0
Socket messages sent: 0
Socket messages received: 0
Signals delivered: 0
Page size (bytes): 4096
Exit status: 0
используйте man time
для руководства /usr/bin/time
и используйте help time
для встроенной информации времени.
Мне нужно было посмотреть на источник, чтобы убедиться, но я предполагаю, что он не совсем "без эффекта", но он, вероятно, еще меньше, чем usleep(1)
- все еще есть служебные данные вызова функции, которые могут быть измеримы в жесткая петля, даже если вызов библиотеки просто проверяет свои аргументы и сразу возвращается, избегая более обычного процесса настройки таймера/обратного вызова и вызова планировщика.
Эта документация вернулась с 1997 года, но не уверен, что она применима к текущему RHEL5, моя справочная страница системы Redhat для usleep не указывает, что время сна 0 не влияет.
Параметр, который вы проходите, является минимальным временем для сна. Там нет гарантии, что поток проснется после точно указанного времени. Учитывая определенную динамику планировщика, это может привести к более длительным, чем ожидалось, задержкам.
usleep()
и sleep()
преобразуются в системные вызовы nanosleep()
. Попробуйте strace
вашу программу, и вы ее увидите. Из Руководство пользователя nanosleep():
nanosleep() suspends the execution of the calling thread until either
at least the time specified in *req has elapsed, or the delivery of a
signal that triggers the invocation of a handler in the calling
thread or that terminates the process.
Итак, я думаю, что umpep (0) будет генерировать прерывание и контекстный переключатель.
Это также зависит от того, будет ли udelay реализован как цикл занятости для коротких длительностей.
По моему опыту он имеет один эффект: он вызывает прерывание.
Это хорошо, чтобы выпустить процессор на минимальное время в многопоточном программировании.
Хорошо. Сегодня я обнаружил, что usleep (0) все еще стоит много времени. Так что в следующий раз