Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/reporting-services/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C 如何使线程睡眠/阻塞达到纳秒(或至少毫秒)?_C_Linux_Pthreads_Sleep - Fatal编程技术网

C 如何使线程睡眠/阻塞达到纳秒(或至少毫秒)?

C 如何使线程睡眠/阻塞达到纳秒(或至少毫秒)?,c,linux,pthreads,sleep,C,Linux,Pthreads,Sleep,如何将线程(可能是进程)阻塞纳秒或毫秒(至少)时间段 请注意,我不能使用sleep,因为sleep的参数总是以秒为单位。试试看。是的,这不会给你纳秒级的精度,但微秒级也可以工作=>毫秒。在一般的Linux操作系统上,精确的纳秒级分辨率是不可能的,因为Linux发行版通常不是(硬的)实时操作系统。如果你真的需要对时间的细粒度控制,考虑使用这样的操作系统。 Wikipedia在这里列出了一些实时操作系统:(注意,它并没有说它们是软实时还是硬实时,所以你需要做一些研究)。使用pthread的任何睡眠变

如何将线程(可能是进程)阻塞纳秒或毫秒(至少)时间段


请注意,我不能使用sleep,因为sleep的参数总是以秒为单位。

试试看。是的,这不会给你纳秒级的精度,但微秒级也可以工作=>毫秒。

在一般的Linux操作系统上,精确的纳秒级分辨率是不可能的,因为Linux发行版通常不是(硬的)实时操作系统。如果你真的需要对时间的细粒度控制,考虑使用这样的操作系统。
Wikipedia在这里列出了一些实时操作系统:(注意,它并没有说它们是软实时还是硬实时,所以你需要做一些研究)。

使用pthread的任何睡眠变体,都不能保证其行为。由于内核不知道不同的线程,所以所有线程都可以休眠。因此,需要一个pthread库而不是内核能够处理的解决方案

一个更安全、更干净的解决方案是pthread_cond_timedwait

pthread_mutex_t fakeMutex = PTHREAD_MUTEX_INITIALIZER;
pthread_cond_t fakeCond = PTHREAD_COND_INITIALIZER;

void mywait(int timeInSec)
{
struct timespec timeToWait;
struct timeval now;
int rt;

gettimeofday(&now,NULL);

timeToWait.tv_sec = now.tv_sec + timeInSec;
timeToWait.tv_nsec = now.tv_usec*1000;

pthread_mutex_lock(&fakeMutex);
rt = pthread_cond_timedwait(&fakeCond, &fakeMutex, &timeToWait);
pthread_mutex_unlock(&fakeMutex);
printf("\nDone\n");
}

void* fun(void* arg)
{
printf("\nIn thread\n");
mywait(5);
}

int main()
{
pthread_t thread;
void *ret;

pthread_create(&thread, NULL, fun, NULL);
pthread_join(thread,&ret);
}
对于pthread_cond_timedwait,需要指定从当前时间开始等待的时间


现在,通过使用函数mywait(),只有调用它的线程将休眠,而不是其他pthread。

允许您将休眠精度指定为纳秒。但是,由于内核/CPU的限制,睡眠的实际分辨率可能要大得多。

一种相对可移植的方法是使用
select()
pselect()
而不使用文件描述符:

void sleep(unsigned long nsec) {
    struct timespec delay = { nsec / 1000000000, nsec % 1000000000 };
    pselect(0, NULL, NULL, NULL, &delay, NULL);
}

nanosleep
clock\u nanosleep
是您应该使用的函数(后者允许您指定绝对时间而不是相对时间,并使用单调时钟或其他时钟而不仅仅是实时时钟,如果操作员重置它,它可能会向后运行)

但是要注意,你的分辨率很少会超过几微秒,而且它总是将睡眠时间缩短,而不是缩短。(无论如何,舍入通常是不可能的,因为在大多数机器上,进入和退出内核空间需要一微秒以上的时间。)


此外,如果可能的话,我建议使用一个阻止等待事件的调用,而不是在很短的时间间隔内睡觉然后进行轮询。例如,
pthread\u cond\u wait
pthread\u cond\u timedwait
sem\u wait
sem\u timedwait
选择
读取
,等等。根据线程执行的任务以及它与其他线程同步和/或与外部世界通信的方式。

在可访问多个硬件计时器的嵌入式系统上,为纳秒或微秒等待创建高速时钟。创建宏以启用和禁用它,并在定时器中断服务例程中处理高分辨率处理



如果浪费电源和忙碌等待不是问题,请执行一些no op指令-但请验证编译器没有优化no ups输出。尝试使用volatile类型。

您能解释一下为什么需要如此细粒度的等待吗?一种实现用户定义计时器的方法。请参阅堆栈溢出问题。“纳秒或可能是毫秒”nano/milli=1/1.000.000--您应该确定要使用哪一种。纳秒大约是2-3个CPU周期(假设为2-3 GHz),因此大约有一个或两个机器指令。那么,仅仅调用计时器函数并从中返回,就需要24到500纳秒(以防缓存和/或TLB未命中)。到目前为止,越精细并不一定越好,因为越精细并不意味着越精确。操作系统提供的等待/超时功能(参见R.的答案)是您可以合理获得的最佳功能。任何比这更好的东西都是愚蠢的。有什么东西可以阻挡纳秒吗?假设用户给等待时间:
2.0000045
,这将失败。即使unix系统或其他系统支持非秒,它也会受到CPU速度的限制。让我们看看原因。考虑2.5 GHz处理器。在一秒钟内,它可以执行大约10^8个处理器命令,这意味着每微秒大约有100个操作=>可以在这个处理器上处理这种复杂的操作,但是每纳秒0.1次操作=>即使有这种粒度的支持,处理器也无法正确测量时间。
usleep
在POSIX 2003中被淘汰,并在2008年被删除。我们没有使用市场上任何可用的商用Linux O/S。我们使用我们自己的发行版。内核非常了解线程,从内核的角度来看,它们只是共享内存和其他状态的独立进程。这个答案有错误的信息<代码>睡眠及其变体用于调用线程,而不是进程。但是,使用
pthread\u cond\u wait
而不是sleep函数可能是一个非常好的主意,特别是如果微小睡眠的原因是为了轮询某些条件的话。@Douglas:如果我没有弄错的话,内核不知道用户级线程。这就是为什么当一个用户级线程进行阻塞系统调用时,所有用户级线程都会被阻塞。但这不适用于内核线程。@kingmasher1:你说得对。内核只知道内核线程。它没有关于用户级线程的信息,因此也没有问题。在高端机器上,它真的可以以亚微秒的分辨率睡眠(不过不会小很多,可能500-900纳秒是你能达到的最短睡眠时间)。任何带有
pselect
的系统几乎肯定也会有
nanosleep
。它们都是由POSIX发明的,我认为是同时添加的。这是一个很好的例子,但是我们的CE Linux支持nanosleep,但是,为了清晰和将来的实现,您的代码很有用。谢谢。这不能按原样编译。@LotoLo添加了
struct
,没有注意到它有C标记。