定時器與線程的同步-(sync between timer and thead)

基站開發的時候,我們需要做一個debug工具,以便將來做外場測試的時候用。

工具中有一個測量項是需要計算數據的速率。那麼我們都知道,除了在數據收集的地方做累加以外,還需要有一個定時器做時鐘的參考。

事實上數據是在線程中接收的,1ms內可能收到好幾個包,沒收到一個數據包,就對數據量做一次累加。 然後我們在外部起一個定時器用來週期性的收集並復位。

看似很簡單,但是我們遇到的問題是,當我們解析出來發現,我們收集的數據有時候會有誤差的。


經過調查,我們發現,定時器與線程在處理同一個變量的時候存在同步的問題,在這個問題上,我們可以將定時器看成是一個線程了。

上面問題的解決方法:不再timer中進行寫操作,而是通過 crt_value - old_value 來統計。

我們可以通過下面的小程序進行驗證:

#include <stdio.h>
#include <unistd.h>
#include <signal.h>
#include <time.h>
#include <pthread.h>
#include <sys/time.h>
#include <sys/types.h>

int g_num = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void action()
{
        //pthread_mutex_lock(&mutex);
        printf("timer:%d\n", g_num);
        g_num = 0;
        //pthread_mutex_unlock(&mutex);
}
void action2(void *arg)
{
        while(1)
        {
                //pthread_mutex_lock(&mutex);
                g_num++;
                printf("pthread: %d\n", g_num);
                //pthread_mutex_unlock(&mutex);
        }
}

void init_timer()
{
        struct itimerval val;
        val.it_value.tv_sec = 0;
        val.it_value.tv_usec = 1;
        val.it_interval = val.it_value;
        setitimer(ITIMER_REAL, &val, NULL);
}

int main()
{
        pthread_t pid;
        struct itimerval val;
        signal(SIGALRM, action);
        init_timer();
        pthread_mutex_init(&mutex, NULL);
        pthread_create(&pid, NULL, (void*)action2, NULL);
        while(1)
                ;
        return 0;
}
沒有加鎖的情況下,結果是:


顯而易見,定時器獲取的數據不是實時的。

解決方法就通過加互斥鎖。這裏我就不做演示,有興趣的可以自己在上面的程序中取消註釋,在跑一面就可以了。

然後互斥鎖的判斷是需要消耗資源的,所以最終我們接受了誤差,而沒有通過加鎖來實現精度。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章