我在g ++ 4.8.2中编译了以下源代码
#include "mpmc.hpp"
#include <semaphore.h>
#include <signal.h>
using namespace std;
mpmc_bounded_queue<std::string> mq(2048) ;
volatile int counter1=0 ;
volatile int counter2=0 ;
#define LOOP 1000000
void gexit(int gub)
{
printf("(%d),(%d)\n",counter1,counter2) ;
exit( 0 ) ;
}
int main(int argc, char* argv[])
{
signal(SIGINT, gexit);
signal(SIGTERM, gexit);
void *func1(void *);
void *func2(void *);
pthread_t tid ;
long int icnt = 0;
pthread_create(&tid, NULL, &func1 , (void *) icnt );
pthread_create(&tid, NULL, &func1 , (void *) icnt );
pthread_create(&tid, NULL, &func1 , (void *) icnt );
pthread_create(&tid, NULL, &func2 , (void *) icnt );
pthread_create(&tid, NULL, &func2 , (void *) icnt );
while( 1 )
sleep( 500 ) ;
}
void *func2(void * inum)
{
pthread_detach(pthread_self());
int iret = 0 ;
while(1){
while( 1 ){
std::string s ;
if( mq.dequeue(s) ){
iret = __sync_add_and_fetch(&counter2,1) ;
break ;
}else{
usleep( 1 ) ;
continue ;
}
//usleep( 10 ) ;
}//while
}//while
}
void *func1(void * inum)
{
pthread_detach(pthread_self());
char ptr[11]={0} ;
sprintf(ptr,"%08d",0) ;
string s(ptr) ;
while(1){
while( 1 ){
if( mq.enqueue(s) ){
__sync_add_and_fetch(&counter1,1) ;
break ;
}
usleep(100) ;
if( counter1 >= LOOP )
break ;
continue ;
}//while
if( counter1 >= LOOP )
break ;
usleep(1) ;
} //while
printf("func1 done \n") ;
}
mpmc.hpp是从这里开始的无锁定队列: http://www.1024cores.net/home/lock-free-algorithms/queues/bounded-mpmc-queue
现在,我编译它: g ++ --std = c ++ 11 -Werror -O2 testprint.cpp -pthread -o testprint.exe
运行它将获得以下内容:
func1 done
只有一个“func1完成”,然后按control-c print:(1000000),(1000000)
如果我按以下方式编译: g ++ --std = c ++ 11 -Werror testprint.cpp -pthread -o testprint.exe
运行它将获得以下内容:
func1 done
func1 done
func1 done
全部三个“func1完成”,然后按control-c打印:(1000002),(1000002)
我认为没有-O2的编译更有意义,也是,-O2会 获得第一次“func1完成”需要大约45秒,但没有-O2 只需17秒即可完成所有“func1 done”
我是否知道g ++优化器在这种情况下会做什么导致这种情况发生?