c -为什么这个变量没有被优化出来

  • 本文关键字:优化 变量 c linux
  • 更新时间 :
  • 英文 :


我有一个简单的代码片段,其中编译器优化了变量"done">

#include <pthread.h>
#include <stdbool.h>
bool done = false;
void *func(void *args)
{
done = true;
return NULL;
}
main()
{
pthread_t p1;

pthread_create(&p1, NULL, func, NULL);
printf("waitingn");

while(!done)
{}
printf("moving on...n");
}

在这里,如果没有volatile关键字,变量"done"被优化掉并进入无限循环。

我正在编译使用:

gcc -O2 volatile.c -lpthread

但是当我使用简单的func()版本:

#include <stdbool.h>
bool done = false;
void func()
{
done = true;
}
main()
{
func();
printf("waitingn");
while(!done)
{}
printf("moving on...n");
}

但是这里变量"done"没有优化出来,两者有什么区别?

编译器在第二种情况下猜出了"done"会改变一些方式,但不是在Pthread的情况下?

我的GCC版本是:

gcc -版本gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609

在这两种情况下,变量done都没有优化出来。优化出来的(在这两种情况下)是while循环中doneread。这个读操作被提升到循环之外,在循环之前发生一次;然后循环运行0次或无限次,这取决于在循环之前读取的done的值。它实际上变成了

if (!done)
while (true) {}
else
while (false) {}

,然后进一步简化为

if (!done) while (true) {}

建议代码如下:

  1. 包含丢失的头文件:'stdio.h'用于'printf()'和'fprintf()'
  2. 正确退出线程函数
  3. 正确地使'主线程'等待子线程以避免"燃烧所有可用的CPU周期">
  4. 正确检查调用'pthread_create()'的状态——这个函数不设置'errno'
  5. 正确处理'args'参数以避免编译器警告
  6. 消除'无用'变量'done'
  7. 为'main()'使用有效签名
  8. 包含适当的水平间距以提高可读性
  9. 删除不需要的标头' stdbook .h'

现在,建议的代码:

#include <pthread.h>
#include <stdio.h>  // printf(), fprintf()
#include <stdlib.h> // exit() and EXIT_FAILURE
//bool done = false;
void *func( void *args )
{
(void)args;   // eliminate warning about unused argument
//done = true;
//return NULL;
pthread_exit( NULL );
}
int main( void )   //use valid signature for 'main()'
{
pthread_t p1;

if( pthread_create( &p1, NULL, func, NULL ) != 0 )
{
fprintf( stderr, "call to pthread_create() failedn" );
exit( EXIT_FAILURE );
}
printf( "waitingn" );
pthread_join( p1, NULL );  // wait for sub thread to exit

//while(!done)
//{}
printf( "moving on...n" );
}

相关内容

  • 没有找到相关文章

最新更新