在win32上使用pthread_cond_timedwait发出问题

时间:2013-08-27 12:12:03

标签: c++ c windows pthreads pthreads-win32

我正在将pthread用于Windows和Linux环境中使用的程序。 对于Windows,我使用pthread for Win 32 ver 2.9.1(最新版)。

我需要使用pthread_cond_timedwait等待微秒分辨率的时间。 在Linux上一切正常,但在Windows上,尽管我的努力,我不能低于秒的分辨率。

这是我使用pthread函数的方式:

int PTMon::wait(time_t sec, long nsec)
{
   timespec abstime;
   struct timeval    tp;
   gettimeofday(&tp, NULL);
   abstime.tv_sec  = tp.tv_sec + sec;
   abstime.tv_nsec = tp.tv_usec * 1000 + nsec;

   long sc; 
   if((sc = abstime.tv_nsec / 1000000000L) != 0){
     abstime.tv_sec += sc;
     abstime.tv_nsec %= 1000000000L;
   }

   return pthread_cond_timedwait(&cv_, &mutex_, &abstime);
}

这是我使用的gettimeofday()的实现:

if defined(_MSC_VER) || defined(_MSC_EXTENSIONS)
#define DELTA_EPOCH_IN_MICROSECS    11644473600000000Ui64
#define DELTA_EPOCH_IN_MICROSECS10      116444736000000000Ui64
#else
#define DELTA_EPOCH_IN_MICROSECS    11644473600000000ULL
#define DELTA_EPOCH_IN_MICROSECS10      116444736000000000ULL
#endif

int gettimeofday(struct timeval *tv, struct timezone *tz)
{
FILETIME ft;
unsigned __int64 tmpres = 0;
static int tzflag = 0;

if (NULL != tv)
{
    GetSystemTimeAsFileTime(&ft);

    tmpres |= ft.dwHighDateTime;
    tmpres <<= 32;
    tmpres |= ft.dwLowDateTime;

    tmpres /= 10;  /*convert into microseconds*/
    /*converting file time to unix epoch*/
    tmpres -= DELTA_EPOCH_IN_MICROSECS; 
    tv->tv_sec = (long)(tmpres / 1000000UL);
    tv->tv_usec = (long)(tmpres % 1000000UL);
}

if (NULL != tz)
{
    if (!tzflag)
    {
        _tzset();
        tzflag++;
    }
    tz->tz_minuteswest = _timezone / 60;
    tz->tz_dsttime = _daylight;
}

return 0;
}

我使用了这个简单的测试程序:

char tbuf[128];

int main(int argc, char* argv[]){
CYG_InitTimers();

cyg_tim_t t1, t2, dt;
int i = 0;
int wres = 0;

while(i++ < 100){
    CYGMARK1(&t1);
    wres = mon.wait(3, 50*MSEC_F); //this should wait for 3 sec and 50 msec
    CYGMARK1(&t2);
    dt = DIFFT(t1, t2);
    memset(tbuf, 0, sizeof(tbuf));
    sprintf(tbuf,   "S%03llu - MS%03llu - US%03llu",
    (dt / CYG_ONEBILLION), 
    (dt / CYG_ONEMILLION) % CYG_ONEKAPPA,
    (dt / CYG_ONEKAPPA) % CYG_ONEKAPPA);
    printf(" wt(%d): %s\n",wres, tbuf);
}

return 0;
}

LINUX OUTPUT:

devel@thor:/mnt/D/prjs/cr_prj/src/test$ ./test
 wt(110): S003 - MS050 - US634
 wt(110): S003 - MS051 - US386
 wt(110): S003 - MS050 - US380
 wt(110): S003 - MS051 - US765
 wt(110): S003 - MS050 - US470
 wt(110): S003 - MS051 - US520
 wt(110): S003 - MS050 - US573
 wt(110): S003 - MS050 - US498
 wt(110): S003 - MS051 - US459
 wt(110): S003 - MS050 - US665
 wt(110): S003 - MS051 - US563
 wt(110): S003 - MS051 - US564
 wt(110): S003 - MS050 - US481
 wt(110): S003 - MS051 - US650
 wt(110): S003 - MS050 - US463
 wt(110): S003 - MS050 - US616
 wt(110): S003 - MS050 - US947
 wt(110): S003 - MS050 - US570
 wt(110): S003 - MS050 - US508
 wt(110): S003 - MS050 - US565
 wt(110): S003 - MS050 - US549
....

WIN OUTPUT:

 wt(10060): S002 - MS629 - US885
 wt(10060): S002 - MS998 - US859
 wt(10060): S003 - MS000 - US007
 wt(10060): S003 - MS000 - US013
 wt(10060): S003 - MS000 - US029
 wt(10060): S003 - MS023 - US701
 wt(10060): S003 - MS023 - US245
 wt(10060): S003 - MS023 - US697
 wt(10060): S003 - MS023 - US225
 wt(10060): S002 - MS999 - US730
 wt(10060): S003 - MS002 - US711
 wt(10060): S003 - MS010 - US663
 wt(10060): S002 - MS999 - US226
 wt(10060): S003 - MS000 - US214
 wt(10060): S002 - MS999 - US698
 wt(10060): S003 - MS000 - US215
 wt(10060): S003 - MS000 - US233
 wt(10060): S002 - MS999 - US210
 wt(10060): S003 - MS000 - US215
 wt(10060): S002 - MS999 - US215
 wt(10060): S003 - MS000 - US237
 wt(10060): S003 - MS000 - US205
 wt(10060): S002 - MS999 - US218
 wt(10060): S003 - MS000 - US223
 wt(10060): S003 - MS000 - US228
 wt(10060): S002 - MS999 - US210
 wt(10060): S003 - MS000 - US216
 wt(10060): S002 - MS999 - US097
 wt(10060): S003 - MS000 - US197
 wt(10060): S003 - MS000 - US210
...

我哪里错了?

0 个答案:

没有答案