我有以下源代码由g ++ 4.8.2编译:
g++ --std=c++11 testx.cpp -pthread -lrt -O2 -o testx.exe
g++ --std=c++11 testx.cpp -pthread -lrt -o testy.exe
layout.h:
#pragma once
typedef struct DBInfo_
{
volatile int seqno ;
char groupname[32] ;
char action[32] ;
int booklayer ;
} DBInfo ;
#define DBARRAYSIZE 100
static DBInfo *conf;
#define STATE_FILE "/strategy2/test.shared"
testx.cpp:
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/mman.h>
#include <unistd.h>
#include <fcntl.h>
#include <sys/types.h>
#include <sys/file.h>
#include <ctype.h>
#include <pthread.h>
#include <sys/stat.h>
#include <assert.h>
#include "layout.h"
int g_DBSharedMemIdx = 0 ;
volatile int iGlbErrorSeqLock = 0 ;
void create_shmem(void)
{
int shm_fd;
if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_EXCL | O_RDWR),
(S_IREAD | S_IWRITE))) > 0 ) {
printf("O_CREAT | O_EXCL | O_RDWR \n"); /* We are the first instance */
}
else if((shm_fd = shm_open(STATE_FILE, (O_CREAT | O_RDWR),
(S_IREAD | S_IWRITE))) < 0)
{
printf("Could not create shm object. \n");
exit( 0 ) ;
}
int iTotalByte = sizeof(DBInfo)*DBARRAYSIZE ;
ftruncate(shm_fd, iTotalByte );
conf = (DBInfo*) mmap(0, iTotalByte , (PROT_READ | PROT_WRITE), MAP_SHARED, shm_fd, 0) ;
if(conf == MAP_FAILED)
{
printf(" mmap error ....\n") ;
exit( 0 ) ;
}
g_DBSharedMemIdx = 0 ;
(conf+g_DBSharedMemIdx)->seqno = 0 ;
strcpy( (conf+g_DBSharedMemIdx)->groupname,"" ) ;
strcpy( (conf+g_DBSharedMemIdx)->action,"" ) ;
(conf+g_DBSharedMemIdx)->booklayer = 0 ;
}//create_shmem
int getDBInfo(DBInfo& pDBInfo)
{
if( pDBInfo.seqno == (conf+g_DBSharedMemIdx)->seqno)
return 0 ;
volatile int ilocalseqno1 = 0 , ilocalseqno2 = 0 ;
volatile int icnt=0;
while( 1 ){
icnt++ ;
if( icnt >= 10000 ){
iGlbErrorSeqLock = 1 ;
break ;
}
ilocalseqno1 = (conf+g_DBSharedMemIdx)->seqno ;
if( ilocalseqno1 % 2 ){
printf("***************************************************************************** \n");
continue;
}
strcpy( pDBInfo.action,(conf+g_DBSharedMemIdx)->action ) ;
pDBInfo.booklayer = (conf+g_DBSharedMemIdx)->booklayer ;
ilocalseqno2 = (conf+g_DBSharedMemIdx)->seqno ;
if( ilocalseqno1 != ilocalseqno2 ){
printf("***************************************************************************** \n");
continue;
}
pDBInfo.seqno = ilocalseqno2 ;
break ;
} //while
if( iGlbErrorSeqLock == 1 )
return -1 ;
return 1 ;
}//getDBInfo
void *ThreadONE(void *param)
{
printf("TestThread...(%p)\n",param) ;
pthread_detach(pthread_self());
while( 1 ){
(conf+g_DBSharedMemIdx)->seqno++ ;
strcpy( (conf+g_DBSharedMemIdx)->groupname,"group1" ) ;
strcpy( (conf+g_DBSharedMemIdx)->action,"RUN" ) ;
(conf+g_DBSharedMemIdx)->booklayer = 3 ;
if( (conf+g_DBSharedMemIdx)->seqno % 2 == 1 )
(conf+g_DBSharedMemIdx)->seqno++ ;
usleep( 1 ) ;
}//while
}//ThreadONE
void *ThreadTWO(void *param)
{
DBInfo pDBInfo ;
printf("TestThread...(%p)\n",param) ;
pthread_detach(pthread_self());
int icnt = 0 ;
while( 1 ){
int iret = getDBInfo(pDBInfo);
if( iret < 0 ){
printf("iGlbErrorSeqLock happened \n") ;
assert( iGlbErrorSeqLock == 100 );
}else if(iret == 1){
icnt++ ;
//printf("icnt=(%d)\n",icnt);
}
usleep( 1 ) ;
}//while
}//ThreadTWO
int main(int argc, char** argv)
{
create_shmem();
sleep( 1 ) ;
pthread_t tid ;
pthread_create(&tid , NULL, ThreadONE, (void*)(long)3);
pthread_create(&tid , NULL, ThreadTWO, (void*)(long)3);
while( 1 )
sleep( 5 ) ;
} //main
testy.exe(在没有-O2的情况下编译)运行每秒会看到“**************”2次,
testx.exe(用-O2编译)运行会看到“***********”不太容易。
我有这个测试,因为在我的原始资源中,有时会调用函数 如果用-O2编译,像getDBInfo将被困在无限循环中, 没有-O2就可以了,所以我很好奇编译器在做什么 getDBInfo函数,根据它应该怎么做。