0

Windows 環境と Linux 環境の両方で使用されるプログラムに pthread を使用しています。Windows の場合、Win 32 バージョン 2.9.1 (最新) の pthread を使用しています。

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 出力:

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
....

勝つ出力:

 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
...

どこが間違っていますか?

4

0 に答える 0