定時器並不是一種併發[線程],而是一種延遲,是一種異步,由當前線程執行,即如果定時器任務中有阻塞,會阻塞主線程。
alarm
gettimer/settimer
共同點:使用信號;
不同點:settimer可以自動重啓和有三個獨有模式,並且時間精度不僅僅只有秒。
#include <sys/time.h>
int settimer (int which,
const struct itimerval *value,
struct itimerval *ovalue);
// which ITIMER_REAL 測量真實時間,如果調試模式中,斷點停止前時間不同,不同時間觸發
// ITIMER_VIRTUAL 進程用戶空間代碼執行減少,指定的進程時間過去後
// ITIMER_PROF 與ITIMER_VIRTUAL共用,衡量進程消耗的用戶時間和內核時間
// value itimerval
struct itimerval {
struct timeval it_interval; // 下一次delay時間
struct timeval it_value; // settimer設置一個過期時間爲it_value的定時器
// 一旦時間超過it_value,內核使用it_interval的時長重啓定時器
};
高級定時器[Linux系統編程 P372,這本書推薦反覆讀,但是其中不好的地方在於某些章節寫了部詳細,結構編排有點亂,例如高級定時器],更加多形式,同時更加複雜
創建定時器
#include <signal.h>
#include <time.h>
int timer_create(clockid_t clockid,
struct sigevent *evp,
timer_t *timerid); // 調用成功會將定時器標記保存在 timerid中
// clockid_t CLOCK_REALTIME
// CLOCK_PROCESS_CPUTIME_ID
//
struct sigevent {
union sigval sigev_value;
int sigev_signo;
int sigev_notify;
void (*sigev_notify_function)(union sigval);
pthread_attr_t *sigev_notify_attributes;
};
union sigval {
int sival_int;
void *sival_ptr;
};
// sigev_notify SIGEV_NONE 定時器到期時,什麼也不發生
// SIGEV_SIGNAL 定時器到期時,內核給進程發送一個sigev_signo指定的信號
// SIGEV_THREAD 定時器到期時,會產生一個新線程,執行 sigev_notify_function將
// sigev_value作爲它唯一的參數,這個線程函數返回時終止