Подтвердить что ты не робот

Эффект usleep (0) в С++ на Linux

Документация для 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
4b9b3361

Ответ 1

Технически это не должно иметь никакого эффекта. Но вы должны помнить, что переданное значение используется как минимум, а не абсолютное, поэтому система может использовать наименьший возможный интервал.

Ответ 2

Я просто хотел указать на команду времени, используемую здесь. Вы должны использовать /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 для встроенной информации времени.

Ответ 3

Мне нужно было посмотреть на источник, чтобы убедиться, но я предполагаю, что он не совсем "без эффекта", но он, вероятно, еще меньше, чем usleep(1) - все еще есть служебные данные вызова функции, которые могут быть измеримы в жесткая петля, даже если вызов библиотеки просто проверяет свои аргументы и сразу возвращается, избегая более обычного процесса настройки таймера/обратного вызова и вызова планировщика.

Ответ 4

Эта документация вернулась с 1997 года, но не уверен, что она применима к текущему RHEL5, моя справочная страница системы Redhat для usleep не указывает, что время сна 0 не влияет.

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

Ответ 5

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) будет генерировать прерывание и контекстный переключатель.

Ответ 6

Это также зависит от того, будет ли udelay реализован как цикл занятости для коротких длительностей.

Ответ 7

По моему опыту он имеет один эффект: он вызывает прерывание.
Это хорошо, чтобы выпустить процессор на минимальное время в многопоточном программировании.

Ответ 8

Хорошо. Сегодня я обнаружил, что usleep (0) все еще стоит много времени. Так что в следующий раз