Влияние usleep (0) в C++ на Linux

на документация для usleep гласит, что вызов usleep(0) не имеет никакого эффекта. Однако в моей системе (RHEL 5.2), запускающей небольшие фрагменты кода C++ ниже, я нахожу, что он на самом деле имеет тот же эффект, что и usleep(1). Можно ли этого ожидать, и если да, то почему существует несоответствие между документацией и тем, что я вижу в реальной жизни?

выставки А

код:

#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

7 ответов


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


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

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


usleep() и sleep() переводится как nanosleep() система звонков. Попробуй!--4--> ваша программа, и Вы ее увидите. От 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.

поэтому я думаю, что ulseep (0) создаст прерывание и контекстный переключатель.


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


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