1. 程式人生 > >時間函式和定時執行緒(linux C )

時間函式和定時執行緒(linux C )

1.日期時間輸出格式:

printf("%04d-%02d-%02d\n",year,month,day);

輸出:1994-02-07  d表示輸出整數、2表示寬度、0表示不足兩位前面補0,右對齊。

2.signal函式:

signal(SIGALRM,statistic);

執行緒收到SIGALRM訊號,暫停手頭工作,開始執行void statistic(int)函式。statistic執行完後,執行緒回到被中斷的那一點繼續執行後面的語句。

3.setitimer函式:

int res = setitimer(ITIMER_REAL,&tick,NULL);

if(res != 0)

std::cout<<"set timer fail"<<std::endl;

引數解釋:

ITIMER_REAL:指明定時器到時後發訊號SIGALRM

tick:struct itimerval的變數,itimerval結構如下:

struct itimerval { struct timeval it_interval; struct timeval it_value; }; struct timeval { long tv_sec; long tv_usec; }; tick.it_value指明定時器第一次觸發時間,tick.it_interval指明觸發間隔。

tick.it_value.tv_sec = 10;

tick.it_value.tv_usec = 0;

tick.it_interval.tv_sec = 5;

tick.it_interval.tv_usec = 0;

int res = setitimer(ITIMER_REAL,&tick,NULL);

if(res != 0)

std::cout<<"set timer fail"<<std::endl;

定時器10秒後將會觸發,以後每隔5秒觸發一次。觸發後發SIGALRM訊號。

成功返回0。

4.pause函式:

pause();

執行緒會被掛起,直至被訊號中斷。執行緒被喚醒後,繼續執行pause後面的語句。

防止執行緒退出,使定時執行緒連續工作:

while(1)

pause();

5.time函式:

time_t t = time(NULL);

返回的結果是一個time_t型別,其實就是一個大整數,其值表示從CUT(Coordinated Universal Time)時間1970年1月1日00:00:00(稱為UNIX系統的Epoch時間)到當前時刻的秒數。

6.localtime函式:

struct tm *tb = localtime(&t); //上面得到的t

把從1970-1-1零點零分到某一時間點經過的秒數轉換為本地時間。

此函式獲得的tm結構體的時間是日曆時間。

struct tm {
          int tm_sec;       /* 秒 – 取值區間為[0,59] */
          int tm_min;       /* 分 - 取值區間為[0,59] */
          int tm_hour;      /* 時 - 取值區間為[0,23] */
          int tm_mday;      /* 一個月中的日期 - 取值區間為[1,31] */
          int tm_mon;       /* 月份(從一月開始,0代表一月) - 取值區間為[0,11] */
          int tm_year;      /* 年份,其值等於實際年份減去1900 */
          int tm_wday;      /* 星期 – 取值區間為[0,6],其中0代表星期天,1代表星期一,以此類推 */
          int tm_yday;      /* 從每年的1月1日開始的天數 – 取值區間為[0,365],其中0代表1月1日,1代表1月2日,以此類推 */
          int tm_isdst;     /* 夏令時識別符號,實行夏令時的時候,tm_isdst為正。不實行夏令時的進候,tm_isdst為0;不瞭解情況時,tm_isdst()為負。*/
          };

月份從0開始,年份從1900開始。

所以給定一個秒數t,對應的真正日期為:

std::cout<<tb->tm_year+1900<<"."<<tb->tm_mon+1<<"."<<tb->tm_mday<<std::endl;

7.mktime函式:

time_t t = mktime(tb); //上面得到的tb

用來將引數tb所指的tm結構的日曆時間轉換成從公元1970年1月1日0時0分0 秒算起至今的UTC時間所經過的秒數。

8.定時執行緒模型,下一小時第一次觸發,以後每隔一小時觸發一次。例如當前為18:39,則17:00第一次觸發。

#include <time.h>
#include <signal.h>
#include <unistd.h>
#include <sys/time.h>


int main(){
	pthread_t tid;
	if(pthread_create(&tid,NULL,func,NULL) != 0){
		std::cout<<"timer thread create fail"<<std::endl;
		return 1;       
	}

	while(1);   //防止主執行緒退出
}

void* func(void*){
	signal(SIGALRM,statistic);     
 
	time_t t1 = time(NULL);
	struct tm *tb = localtime(&t);

	tb->tm_hour++;
	tb->tm_min = 0;
	tb->tm_sec = 0;

	time_t t2 = mktime(tb);

	struct itimerval tick;
	tick.it_value.tv_sec =  t2- t1;
	tick.it_value.tv_usec = 0;
	tick.it_interval.tv_sec = 3600;
	tick.it_interval.tv_usec = 0;

	int res = setitimer(ITIMER_REAL,&tick,NULL);
	if(res != 0)
		std::cout<<"set timer fail"<<std::endl;

	while(1)
		pause();   //執行緒睡在該處。當訊號觸發後,執行緒即刻轉去執行訊號處理函式。完成後,執行pause()後語句,故必須用while(1)迴圈,防止執行緒退出。
}

void statistic(int){
	std::cout<<"statistic work start"<<std::endl;
}