我正在将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
...
我哪里错了?