while(1)的用途; C中的陈述

while(1);目的是什么? 服务? 我知道while(1) (无分号)无限循环,类似于螺旋locking的情况。 但是我不知道while(1); 可用于 ?

示例代码

 if(!condition) { while(1); } 

注意:这不是dowhile()或plain while(1)

请注意,所有语言的有效声明不一定有用的。 它们根据语言的语法是有效的。 可以build立许多类似的“无用的”陈述,如if (1); 。 我看到这样的陈述是有条件的( ifwhile等)和空的陈述的结合; (这也是一个有效的陈述,虽然它显然没有特定的目的)。

这就是说,我遇到while (1); 在安全代码。 当用户使用embedded式设备做了一些非常糟糕的事情时,阻止他们尝试其他任何东西可能是件好事。 while (1); ,我们可以无条件地阻止设备,直到经过authentication的操作员手动重新启动设备。

while(1); 也可以是内核恐慌执行的一部分,虽然for(;;) {}循环似乎是expression无限循环的更常见的方式,并且可能有一个非空的体(例如panic_blink() )。

如果您深入到汇编(从embedded式系统的angular度来看,这更容易理解,或者如果您尝试对引导加载程序进行编程)

你会意识到while循环只是一个jmp指令

 (pseudo code: starting loop address) add ax, bx add ax, cx cmp ax, dx jz (pseudo code: another address location) jmp (pseudo code: starting loop address) 

让我们解释这是如何工作的,处理器将继续执行指令顺序…无论如何。 所以进入这个循环的时候,它会把寄存器bx添加到ax并存储在ax中,将ax添加到寄存器cx并存储到ax,cmp ax,dx(这意味着从ax减去dx)jz指令意味着跳转到另一个地址位置)如果设置了零标志(如果上述减法的结果为0,那么标志寄存器中的位将被设置),然后将jmp设置为开始循环地址(非常简单),然后重做整个过程。

我在这个大会上打扰你的原因是告诉你,这会在C中转化为

 int A,B,C,D; // initialize to what ever; while(true) { A = A + B; A = A + C; if((AD)==0) {break;} } // if((XY)==0){break;} is the // cmp ax, dx // jz (pseudo code: another address location) 

所以想象一下,在汇编中的senario如果你只是有一个非常长的指令列表,并没有结束一个jmp(while循环)重复一些部分或加载一个新的程序或做一些事情…最终处理器将达到最后一条指令,然后加载下面的指令来找不到任何东西(它会冻结或三重故障或什么)。

这就是为什么当你希望程序在触发事件之前什么都不做的时候,你必须使用一个while(1)循环,这样处理器就不停地跳到原来的位置,而不能到达那个空的指令地址。 当事件被触发时,它跳转到事件处理程序指令地址,执行它,清除中断并返回到while(1)循环,只是在等待进一步中断的位置跳转。 顺便说一句,如果你想了解更多关于while(1)的内容,可以称之为超循环(superloop)…只是对于那些疯狂地想要在这一点上争辩和否定评论的人来说,这不是一个汇编教程或者讲座或者任何东西。 这只是简单的英语解释,尽可能简单,忽略了许多底层的细节,如指针和堆栈,以及在某些情况下简化的东西,以获得一个点。 没有人在这里查找文档的准确性,我知道这个C代码不会像这样编译,但是这只是为了演示!

这被标记为C,但我将从C ++透视图开始。 在C ++ 11中,编译器可以自由地优化while(1); 远。

从C ++ 11草案标准n3092,第6.5节第5段(重点是我的):

一个循环,在for语句的for-init语句之外,
– 不会调用库I / O函数
– 不访问或修改易失性对象
– 不执行同步操作(1.10)或primefaces操作(第29章)
可能由执行方式假定终止。 [ 注:这是为了允许编译器转换,例如删除空循环,即使无法证实终止。 – 结束注意]

C11标准有一个类似的条目,但有一个关键的区别。 从C11草案标准n1570(重点是我的):

一个迭代语句, 其控制expression式不是一个常量expression式执行input/输出操作,不访问易失性对象,在其主体中不执行同步或primefaces操作,控制expression式或(在for声明)其expression式-3 ,可以由实现来承担终止。 157)
156)一个省略的控制expression式被一个非零常量(常量expression式)替代。
这是为了允许编译器转换,例如,即使在无法certificate终止的情况下,也可以清除空循环。

这意味着while(1); 可以假定在C ++ 11中终止,但不在C11中终止。 即使如此,注意157(不是绑定)被某些供应商解释为允许他们删除那个空的循环。 while(1); 在C ++ 11和C11中是定义的还是未定义的行为。 因为循环是空的,所以可以在C ++ 11中删除。 在C11中, while(1); 是可certificate的不终止,这是不明确的行为。 由于程序员调用了UB,因此编译器可以自由地执行任何操作,包括删除有问题的循环。

while(1);关于优化编译器的删除while(1);有一些关于stackoverflow的讨论while(1); 。 例如, 编译器是否允许消除无限循环? , 一个空的for循环用作睡眠优化了吗? , 优化一个“while(1);” 在C ++ 0x 。 请注意,前两个是C特定的。

我假设while(1); 不与do循环关联…

while(1);的唯一半有用的实现while(1); 我所看到的是一个等待中断的无所事事的循环; 例如等待SIGCHLD的父进程,表示subprocess已经终止。 在所有subprocess终止之后,父进程的SIGCHLD处理程序可以终止父线程。

它诀窍,但浪费了大量的CPU时间。 这样的用法也许应该执行某种睡眠来周期性地放弃处理器。

embedded式软件的用法是使用看门狗来实现软件重置:

 while (1); 

或者相当但更安全,因为它使意图更清楚:

 do { /* nothing, let's the dog bite */ } while (1); 

如果看门狗启用并且在x毫秒后没有被确认,我们知道它会重置处理器,所以用它来实现软件重置。

一个我曾经看过的地方while(1); 是embedded式编程。

该架构使用主线程来监视事件和工作线程来处理它们。 有一个硬件看门狗定时器( 在这里解释),将在一段时间后执行模块的软复位。 在主线程轮询循环内,它将重置该计时器。 如果主线程检测到不可恢复的错误, while(1); 将被用来捆绑主线程,从而触发看门狗复位。 我相信主张失败是有一段while(1); 以及。

正如其他人所说,这只是一个无限循环,什么都不做,完全类似于

 while (1) { /* Do nothing */ } 

用分号循环确实有一个主体。 当作为一个语句使用时,一个分号是一个空语句 ,循环体是由这个空语句组成的。

为了便于阅读,为了让读者明白null语句是循环的主体,我build议把它写在一个单独的行上:

 while (1) ; 

否则,在“while”行的末尾很容易忽略,通常不会有分号,读者可能会把下一行误认为是循环的主体。

或者使用空的复合语句。

 while(1); 

其实很有用。 特别是当它是一个有某种密码的程序时,你想禁止用户使用该程序,例如,他input了3次错误的密码。 用while(1); 会停止程序的进度,直到程序重新启动后才会发生任何事情,主要是出于安全原因。

这可能被用来等待中断 。 基本上,你初始化所有你需要的东西,并开始等待一些事情发生。 之后,一些特定的function被调用并执行,然后返回到等待状态。

可以按下button,鼠标点击/移动,收到数据等。

更重要的是, 类似的东西通常被UI框架所使用。 它等待有关用户操作的信号。

在AVR芯片组编程中(使用C语言编程语言)这个语句经常用到,它起着事件循环的作用。

假设我想devise一个计数器,所以我可以使用这个代码来实现它:

 void interrupt0() { /* check if key pressed, count up the counter */ } void main() { /* Common inits */ /* Enable interrupt capability and register its routine */ /* Event loop */ while(1); } 

既然情况总是如此,我们可以说我们正在使用math中已知的逻辑重言式。 虽然循环certificate永远是真的,但不会停止循环,除非被代码强制或资源崩溃。

我认为, while(1); 被使用是因为在代码的早些时候在这个线程上设置了一个EventHandler或中断。 当你知道你的代码只能“等待”很短的时间时,使用标准的线程安全locking代码可能会相当昂贵(及时)。 因此,您可以使用while(1);来设置中断和“旋转” while(1); 其中,尽pipe是一个忙等待(不让CPU空闲/服务其他线程)占用很less的周期来build立。

总之,当你的线程等待中断或事件时,这是一个'廉价'的自旋锁。