将nanosec转换为微秒

时间:2017-05-23 09:43:55

标签: c multithreading

我使用以下代码将nano转换为微秒

这段代码主要是罚款,但有时我看到usTick给出的值远远超过当前时间。

对于前。如果usTick中的当前时间是63290061063,则有时此值将为126580061060.如果您看到它是双倍的。

同样,我得到的另一个实例是当前时间是45960787154,但usTick显示为91920787152

typedef unsigned long long TUINT64 
unsigned long long GetMonoUSTick()
{
    static unsigned long long usTick;
    struct        timespec t;
    clock_gettime(CLOCK_MONOTONIC, &t);
    usTick  =  ((TUINT64)t.tv_nsec) / 1000;
    usTick  =  usTick +((TUINT64)t.tv_sec) * 1000000;
    return usTick;
}

2 个答案:

答案 0 :(得分:1)

如果同一进程的多个线程并行访问变量同时用于读/写或写/写这些变量需要保护。这可以通过使用互斥锁来实现。

在这种情况下,局部变量usTick需要受到保护,因为它被定义为static

使用POSIX-threads,代码可能如下所示:

  pthread_mutex_lock(&ustick_mutex);

  usTick  =  ((TUINT64)t.tv_nsec) / 1000;
  usTick  =  usTick +((TUINT64)t.tv_sec) * 1000000;

  pthread_mutex_unlock(&ustick_mutex);

(为清楚起见,遗漏了错误检查)

在使用之前,请务必正确初始化ustick_mutex

答案 1 :(得分:0)

听起来你正在使用线程,而且偶尔会有两个线程同时调用此函数。由于usTickstatic,因此它们使用相同的变量(而不是两个不同的副本)。它们都将纳秒转换为微秒并一个接一个地分配给usTick,然后它们将秒转换为微秒,并将它们都添加到usTick(因此秒被添加两次)。 / p>

编辑 - 我提出的以下解决方案基于两个假设:

  • 如果两个威胁同时调用该函数,clock_gettime()返回的当前时间之间的差异将太小而无关紧要(线程计算的结果之间的差异最多为{{1} }})。
  • 在大多数现代CPU中,读/写整数是原子操作。

我认为您应该可以通过更改:

来解决此问题

<德尔> 1
usTick = ((TUINT64)t.tv_nsec) / 1000;

<德尔>到

usTick = usTick +((TUINT64)t.tv_sec) * 1000000;

我的解决方案的问题在于即使后面的假设是正确的,它也可能不适用于usTick = ((TUINT64)t.tv_nsec) / 1000 + ((TUINT64)t.tv_sec) * 1000000;。因此,例如,这可能发生:

  • 线程A和B在(几乎)同时调用该函数。
  • 主题A以微秒为单位计算当前时间long long
  • 主题B以微秒为单位计算当前时间0x02B3 1F02 FFFF FFFF
  • 线程A将最低有效32位(0x02B3 1F03 0000 0000)写入0xFFFF FFFF
  • 线程B将最低有效32位(usTick)写入0x0000 0000
  • 线程B将最重要的32位(usTick)写入0x02B3 1F03
  • 线程A将最重要的32位(usTick)写入0x02B3 1F02

然后该函数将在两个线程中返回usTick0x02B3 1F02 0000 0000关闭{。}}。

正如@alk所说,使用互斥锁来保护4294967295的读/写