实习总结

一 boost定时器的--------------------------------------------------------------------------------------------------------

(1)简单实用:

   #include 
   
   
    
    
    #include 
    
    
     
     
    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(3));
    
        timer.wait();
        std::cout << "Hello, world!\n";


        return 0;
    }

    
    
   
   
(2)异步的形式:

    void print(const boost::system::error_code& /*e*/)
    {
        std::cout << "Hello, world!\n";
    }
    int main()
    {
        boost::asio::io_service io;
        boost::asio::deadline_timer timer(io, boost::posix_time::seconds(5));

        timer.async_wait(&print);
        io.run();

        return 0;
    }
(3) 上面演示了基本用法,但它只能发生一次. 问题是怎么定义一个重复发生的定时器(就是隔一定的时间它就会发生一次.)呢,下面的代码就是了, 关键在于回调函数中更改了延时不断的延长定时器 

void print(const boost::system::error_code& e,
           boost::asio::deadline_timer* t)
{
  cout<<"ddd"<
   
   
    
    expires_at(t->expires_at()+ boost::posix_time::seconds(1));
  t->async_wait(boost::bind(print,boost::asio::placeholders::error,t));
}

void test1()
{
   boost::asio::io_service io;
   boost::asio::deadline_timer t(io, boost::posix_time::seconds(1));
   t.async_wait(boost::bind(print,boost::asio::placeholders::error,&t));
   io.run();
}

int _tmain(int argc, _TCHAR* argv[])
{ 
  test1();
  system("pause");
  return 0;
}

   
   
二 linux下获取shell命令执行结果:--------------------------------------------------------------------

char strcmd[256] = {0};
 snprintf(strcmd,sizeof(strcmd)-1, "ls -l %s",m_logpath);
 FILE *pf  = popen(strcmd,"r");
 if( NULL == pf)
 {
  ERROR("NULL == pf\n");
  return ;
 }
 char str[1024]={0};
 int count = fread(str,1,sizeof(str)-1,pf);
 //文件不存在
 if(0 == count)
 {
  getLock();
  if(NULL != pfp)
  {
   fflush(pfp);
   pfp = NULL;
  }
  releaseLock();
 }
 else
 {
  char *psubstr = strtok(str," ");
  int columns = 0;
  while(NULL != psubstr)
  {   columns++;
  if(5 == columns)//第5列是文件的大小
  {
   long filesize = atol(psubstr);
   // 日志已经达到最大值。
   if (LHUConfig::GetConfigNumValue(LOGFILE_MAX_SIZE) < filesize)
   {
    char baklogpath[256]= {0};
    strncpy(baklogpath,m_logpath,strlen(m_logpath)-4);
    snprintf(strcmd,sizeof(strcmd)-1, "mv %s %s_%s.log",m_logpath,baklogpath,CURTIME);//CURTIME
    getLock();
    if(NULL != pfp)
    {
     fflush(pfp);
     int ret = system(strcmd);
     if (0 != ret)
     {
      releaseLock();
      ERROR("exec %s error[%d] ! \n ",strcmd,ret);
      return;
     }
     fclose(pfp);
     pfp = NULL;
    }
    releaseLock();
   }
   break;
  }
  psubstr = strtok(NULL," ");
  }      
 }

三 linux和windows下建立多级目录(对于boost的systemfile 的跨平台库获取当前目录有时不稳定只能单独书写)

bool CFileSystem::CreateMuiltDectory(string  muiltPath)
		{
			
#ifdef _RUN_WINDOWS_
			string store[MAX_PATH];
			int flageplus = 0;
			if(1 == PathFileExists(muiltPath.c_str()))
				return true;
			else
			{
				while (!CreateDirectoryA(muiltPath.c_str(), NULL))
				{
					int length = muiltPath.length();
					string temp;
					int i = length - 1;
					for (; muiltPath[i] != '\\'; i--)
					{
						temp += muiltPath[i];
					}
					reverse(temp.begin(), temp.end());
					store[flageplus++] = temp;
					muiltPath = muiltPath.substr(0, i);
				}
				while (--flageplus >= 0)
				{
					muiltPath += "\\" + store[flageplus];
					if (!CreateDirectory(muiltPath.c_str(), NULL))
						return FALSE;
				}
			}
			return TRUE;
#endif
#ifdef _RUN_LINUX_
			char DirName[256];
			strcpy(DirName, muiltPath.c_str());
			int   i=0;
			int len = strlen(DirName);
			if (DirName[len - 1] != '/')
				strcat(DirName, "/");
			len = strlen(DirName);
			for (i = 1; i
   
   
四 精确计时器(跨平台课考虑使用boost中的date_time 库)-----------------------------------------------------------

(1)time()获取当前的系统时间,返回的结果是一个time_t类型,其实就是一个大整数,其值表示从CUT(Coordinated Universal Time)时间1970年1月1日00:00:00(称为UNIX系统的Epoch时间)到当前时刻的秒数.   

void test1()
{
    time_t start,stop;
    start = time(NULL);
    foo();//dosomething
    stop = time(NULL);
    printf("Use Time:%ld\n",(stop-start));
}void test1()
{
    time_t start,stop;
    start = time(NULL);
    foo();//dosomething
    stop = time(NULL);
    printf("Use Time:%ld\n",(stop-start));
}

(2)clock()函数返回从“开启这个程序进程”到“程序中调用clock()函数”时之间的CPU时钟计时单元(clock tick)数,在MSDN中称之为挂钟时间(wal-clock)常量CLOCKS_PER_SEC,它用来表示一秒钟会有多少个时钟计时单元

void test2()
{
    double dur;
    clock_t start,end;
    start = clock();
    foo();//dosomething
    end = clock();
    dur = (double)(end - start);
    printf("Use Time:%f\n",(dur/CLOCKS_PER_SEC));
}

(3)timeGetTime()函数以毫秒计的系统时间。该时间为从系统开启算起所经过的时间,是windows api

void test3()
{
    DWORD t1,t2;
    t1 = timeGetTime();
    foo();//dosomething
    t2 = timeGetTime();
    printf("Use Time:%f\n",(t2-t1)*1.0/1000);
}

(4)QueryPerformanceCounter()这个函数返回高精确度性能计数器的值,它可以以微妙为单位计时.但是QueryPerformanceCounter()确切的精确计时的最小单位是与系统有关的,所以,必须要查询系统以得到QueryPerformanceCounter()返回的嘀哒声的频率.QueryPerformanceFrequency()提供了这个频率值,返回每秒嘀哒声的个数.

void test4()
{
    LARGE_INTEGER t1,t2,tc;
    QueryPerformanceFrequency(&tc);
    QueryPerformanceCounter(&t1);
    foo();//dosomething
    QueryPerformanceCounter(&t2);
    printf("Use Time:%f\n",(t2.QuadPart - t1.QuadPart)*1.0/tc.QuadPart);
}

(5)GetTickCount返回(retrieve)从操作系统启动到现在所经过(elapsed)的毫秒数,它的返回值是DWORD

void test5()
{
    DWORD t1,t2;
    t1 = GetTickCount();
    foo();//dosomething
    t2 = GetTickCount();
    printf("Use Time:%f\n",(t2-t1)*1.0/1000);
}

(6)RDTSC指令,在Intel   Pentium以上级别的CPU中,有一个称为“时间戳(Time   Stamp)”的部件,它以64位无符号整型数的格式,记录了自CPU上电以来所经过的时钟周期数。由于目前的CPU主频都非常高,因此这个部件可以达到纳秒级的计时精度。这个精确性是上述几种方法所无法比拟的.在Pentium以上的CPU中,提供了一条机器指令RDTSC(Read   Time   Stamp   Counter)来读取这个时间戳的数字,并将其保存在EDX:EAX寄存器对中。由于EDX:EAX寄存器对恰好是Win32平台下C++语言保存函数返回值的寄存器,所以我们可以把这条指令看成是一个普通的函数调用,因为RDTSC不被C++的内嵌汇编器直接支持,所以我们要用_emit伪指令直接嵌入该指令的机器码形式0X0F、0X31

inline unsigned __int64 GetCycleCount()
{
    __asm
    {
        _emit 0x0F;
        _emit 0x31;
    }
}


void test6()
{
    unsigned long t1,t2;
    t1 = (unsigned long)GetCycleCount();
    foo();//dosomething
    t2 = (unsigned long)GetCycleCount();
    printf("Use Time:%f\n",(t2 - t1)*1.0/FREQUENCY);   //FREQUENCY指CPU的频率
}

(7)gettimeofday() linux环境下的计时函数,int gettimeofday ( struct timeval * tv , struct timezone * tz ),gettimeofday()会把目前的时间有tv所指的结构返回,当地时区的信息则放到tz所指的结构中.

//timeval结构定义为:
struct timeval{
long tv_sec; /*秒*/
long tv_usec; /*微秒*/
};
//timezone 结构定义为:
struct timezone{
int tz_minuteswest; /*和Greenwich 时间差了多少分钟*/
int tz_dsttime; /*日光节约时间的状态*/
};
void test7()
{
    struct timeval t1,t2;
    double timeuse;
    gettimeofday(&t1,NULL);
    foo();
    gettimeofday(&t2,NULL);
    timeuse = t2.tv_sec - t1.tv_sec + (t2.tv_usec - t1.tv_usec)/1000000.0;
    printf("Use Time:%f\n",timeuse);
}

(8)linux环境下,用RDTSC指令计时.与方法6是一样的.只不过在linux实现方式有点差异.

#if defined (__i386__)
static __inline__ unsigned long long GetCycleCount(void)
{
        unsigned long long int x;
        __asm__ volatile("rdtsc":"=A"(x));
        return x;
}
#elif defined (__x86_64__)
static __inline__ unsigned long long GetCycleCount(void)
{
        unsigned hi,lo;
        __asm__ volatile("rdtsc":"=a"(lo),"=d"(hi));
        return ((unsigned long long)lo)|(((unsigned long long)hi)<<32);
}
#endif


void test8()
{
        unsigned long t1,t2;
        t1 = (unsigned long)GetCycleCount();
        foo();//dosomething
        t2 = (unsigned long)GetCycleCount();
        printf("Use Time:%f\n",(t2 - t1)*1.0/FREQUENCY); //FREQUENCY  CPU的频率
}

 

简单的比较表格如下

序号函数类型精度级别时间
1timeC系统调用<1s
2clcokC系统调用<10ms
3timeGetTimeWindows API<1ms
4QueryPerformanceCounterWindows API<0.1ms
5GetTickCountWindows API<1ms
6RDTSC指令<0.1ms
7gettimeofday linux环境下C系统调用<0.1ms


  总结,方法1,2,7,8可以在linux环境下执行,方法1,2,3,4,5,6可以在windows环境下执行.其中,timeGetTime()和GetTickCount()的返回值类型为DWORD,当统计的毫妙数过大时,将会使结果归0,影响统计结果.
        测试结果,windows环境下,主频为1.6GHz,单位为秒.

1 Use Time:0
2 Use Time:0.390000
3 Use Time:0.388000
4 Use Time:0.394704
5 Use Time:0.407000
6 Use Time:0.398684

  linux环境下,主频为2.67GHz,单位为秒

1 Use Time:1
2 Use Time:0.290000
7 Use Time:0.288476
8 Use Time:0.297843

      由于time()计时函数的精度比较低,多次运行程序时,将会得到不同的结果,时而为0,时而为1

foo()函数如下:

void foo()
{
    long i;
    for (i=0;i<100000000;i++)
    {
        long a= 0;
        a = a+1;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值