1. 程式人生 > >Linux核心時間管理和定時器

Linux核心時間管理和定時器

轉自:http://blog.csdn.net/zhenwenxian/article/details/7643742

時間管理在核心中佔有非常重要的地位。相對於事件驅動,核心中有大量的函式都是基於時間驅動的。核心必須管理系統的執行時間以及當前的日期和時間。

首先搞清楚RTC在kernel內的作用:

linux系統有兩個時鐘:實時時鐘和系統定時器

實時時鐘

    一個是由鈕釦電池供電的“Real Time Clock”也叫做RTC(實時時鐘)或者叫CMOS時鐘,硬體時鐘。當作業系統關機的時候,用這個來記錄時間,但是對於執行的系統是不用這個時間的。當系統啟動時,核心通過讀取RTC來初始化牆上時間,該時間存放在xtime變數中。所謂牆上時間也就是當前的實際時間。

系統定時器

另一個時間是 “System clock”也叫核心時鐘或者軟體時或者叫系統定時器,是由軟體根據時間中斷來進行計數的,系統定時器是核心時間機制中最重要的一部分,它提供了一種週期性觸發中斷機制,即系統定時器以HZ(時鐘節拍率)為頻率自行觸發時鐘中斷。當時鍾中斷髮生時,核心就通過時鐘中斷處理程式timer_interrupt()對其進行處理。
系統定時器完全由作業系統管理,因此也成為系統時鐘或者軟體時鐘。當系統啟動時,核心通過RTC初始化系統定時器,系統定時器接著由作業系統共掌管,進行固定頻率的定時。可以看到,系統時間並不是傳統意義上的那種計時時鐘,而是通過定時這種特殊的方式來表現時間。 核心時鐘在系統關機的情況下是不存在的,所以,當作業系統啟動的時候,核心時鐘是要讀取RTC時間來進行時間同步。並且在系統關機的時候將系統時間寫回RTC中進行同步。

全域性變數jiffies用來記錄自系統啟動以來產生的節拍的總數。它被用來記錄系統自開機以來,已經過了多少tick每發生一次timer interrupt,Jiffies變數會被加一。啟動時,核心將該變數初始化為0,此後,每次時鐘中斷處理程式都會增加該變數的值。因為一秒內時鐘中斷的次數等於Hz,所以jiffes一秒內增加的值也就為Hz,系統執行時間以秒為單位計算,就等於jiffes/Hz

jiffies轉換為秒可採用公式:(jiffies/HZ)計算,

將秒轉換為jiffies可採用公式:(seconds*HZ)計算。

Tick是HZ的倒數,意即timer interrupt每發生一次中斷的時間。如HZ為250時,tick為4毫秒(millisecond)。

jiffies僅是相對於系統啟動的相對時間,如果想獲取absolutetime或wall time,則需要使用RTC,

核心用變數xtime來記錄,當系統啟動時,讀取RTC並記錄在xtime中,當系統halt時,則將walltime寫回RTC,函式do_gettimeofday()來讀取wall time。

系統定時器及其中斷處理程式是核心管理機制的中樞,下面是一些利用系統定時器週期執行的工作(中斷處理程式所做的工作):

    (1) 更新系統執行時間(uptime) jiffes

    (2) 更新當前牆上時間(wall time) xtime

    (3) 在對稱多處理器系統(SMP)上,均衡排程各處理器上的執行佇列

    (4) 檢查當前程序是否用完了時間片(time slice),如果用盡,則進行重新排程

如前所述,Linux核心與RTC進行互操作的時機只有兩個:

  1) 核心在啟動時從RTC中讀取啟動時的時間與日期(LINUX系統時間的 初始化);

通過呼叫rtc_read_time(rtc, &tm);-讀出RTC時間。呼叫  do_settimeofday(&tv);給系統時間xtime初始化。

Alarm.c (kernel\drivers\rtc):static int __init alarm_late_init(void)
Alarm.c (kernel\drivers\rtc):late_initcall(alarm_late_init);

static int __init alarm_late_init(void)
{
    unsigned long   flags;
    struct timespec tmp_time, system_time;

    /* this needs to run after the rtc is read at boot */
    spin_lock_irqsave(&alarm_slock, flags);
    /* We read the current rtc and system time so we can later calulate
     * elasped realtime to be (boot_systemtime + rtc - boot_rtc) ==
     * (rtc - (boot_rtc - boot_systemtime))
     */
    getnstimeofday(&tmp_time);
    ktime_get_ts(&system_time);
    alarms[ANDROID_ALARM_ELAPSED_REALTIME_WAKEUP].delta =
        alarms[ANDROID_ALARM_ELAPSED_REALTIME].delta =
            timespec_to_ktime(timespec_sub(tmp_time, system_time));

    spin_unlock_irqrestore(&alarm_slock, flags);
    return 0;
}


Hctosys.c (kernel\drivers\rtc):int rtc_hctosys(void)
Hctosys.c (kernel\drivers\rtc):late_initcall(rtc_hctosys);

start_kernel()-->late_initcall(rtc_hctosys);-->

-->rtc_hctosys(void)-->err = rtc_read_time(rtc, &tm);--->    do_settimeofday(&tv);

----》xtime = *tv;

int rtc_hctosys(void)
{
    int err = -ENODEV;
    struct rtc_time tm;
    struct timespec tv = {
        .tv_nsec = NSEC_PER_SEC >> 1,
    };
    struct rtc_device *rtc = rtc_class_open(CONFIG_RTC_HCTOSYS_DEVICE);

    if (rtc == NULL) {
        pr_err("%s: unable to open rtc device (%s)\n",
            __FILE__, CONFIG_RTC_HCTOSYS_DEVICE);
        goto err_open;
    }

    err = rtc_read_time(rtc, &tm);
    if (err) {
        dev_err(rtc->dev.parent,
            "hctosys: unable to read the hardware clock\n");
        goto err_read;

    }

    err = rtc_valid_tm(&tm);
    if (err) {
        dev_err(rtc->dev.parent,
            "hctosys: invalid date/time\n");
        goto err_invalid;
    }

    rtc_tm_to_time(&tm, &tv.tv_sec);

    do_settimeofday(&tv);

    dev_info(rtc->dev.parent,
        "setting system clock to "
        "%d-%02d-%02d %02d:%02d:%02d UTC (%u)\n",
        tm.tm_year + 1900, tm.tm_mon + 1, tm.tm_mday,
        tm.tm_hour, tm.tm_min, tm.tm_sec,
        (unsigned int) tv.tv_sec);

err_invalid:
err_read:
    rtc_class_close(rtc);

err_open:
    rtc_hctosys_ret = err;

    return err;
}

  2) 核心在需要時將時間與日期回寫到RTC中。 系統啟動時,核心通過讀取RTC來初始化核心時鐘,又叫牆上時間,該時間放在xtime變數中。

系統睡眠的時候CPU要斷電系統時鐘不工作,所以RTC的睡眠函式rtc_suspend讀出RTC和系統時鐘的時間,計算它們之間的差,然後儲存到靜態變數。系統被喚醒後讀出當前RTC的時間和系統的時間,系統時間應該接近0,因為cpu剛剛恢復上電,將原來儲存的RTC和系統之間的時間差加上剛剛讀到的RTC的時間就是最新的系統時間,將計算出來的時間通過rtc_resume函式呼叫    timekeeping_inject_sleeptime(&sleep_time);重新初始化系統時鐘xtime。如果RTC的時間和系統時間都一樣,那麼他們之間的差為0.

但是有些系統硬體RTC時間是不可以寫,只能夠被讀,那麼他們之間的差就不為0了。

Class.c (kernel\drivers\rtc):static int rtc_suspend(struct device *dev, pm_message_t mesg)

static int rtc_suspend(struct device *dev, pm_message_t mesg)
{
    struct rtc_device    *rtc = to_rtc_device(dev);
    struct rtc_time        tm;
    struct timespec        delta, delta_delta;
    if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
        return 0;

    /* snapshot the current RTC and system time at suspend*/
    rtc_read_time(rtc, &tm);
    getnstimeofday(&old_system);
    rtc_tm_to_time(&tm, &old_rtc.tv_sec);


    /*
     * To avoid drift caused by repeated suspend/resumes,
     * which each can add ~1 second drift error,
     * try to compensate so the difference in system time
     * and rtc time stays close to constant.
     */
    delta = timespec_sub(old_system, old_rtc);
    delta_delta = timespec_sub(delta, old_delta);
    if (delta_delta.tv_sec < -2 || delta_delta.tv_sec >= 2) {
        /*
         * if delta_delta is too large, assume time correction
         * has occured and set old_delta to the current delta.
         */
        old_delta = delta;
    } else {
        /* Otherwise try to adjust old_system to compensate */
        old_system = timespec_sub(old_system, delta_delta);
    }

    return 0;
}

static int rtc_resume(struct device *dev)
{
    struct rtc_device    *rtc = to_rtc_device(dev);
    struct rtc_time        tm;
    struct timespec        new_system, new_rtc;
    struct timespec        sleep_time;

    if (strcmp(dev_name(&rtc->dev), CONFIG_RTC_HCTOSYS_DEVICE) != 0)
        return 0;

    /* snapshot the current rtc and system time at resume */
    getnstimeofday(&new_system);
    rtc_read_time(rtc, &tm);
    if (rtc_valid_tm(&tm) != 0) {
        pr_debug("%s:  bogus resume time\n", dev_name(&rtc->dev));
        return 0;
    }
    rtc_tm_to_time(&tm, &new_rtc.tv_sec);
    new_rtc.tv_nsec = 0;

    if (new_rtc.tv_sec < old_rtc.tv_sec) {
        pr_debug("%s:  time travel!\n", dev_name(&rtc->dev));
        return 0;
    }

    /* calculate the RTC time delta (sleep time)*/
    sleep_time = timespec_sub(new_rtc, old_rtc);

    /*
     * Since these RTC suspend/resume handlers are not called
     * at the very end of suspend or the start of resume,
     * some run-time may pass on either sides of the sleep time
     * so subtract kernel run-time between rtc_suspend to rtc_resume
     * to keep things accurate.
     */
    sleep_time = timespec_sub(sleep_time,
            timespec_sub(new_system, old_system));

    if (sleep_time.tv_sec >= 0)
        timekeeping_inject_sleeptime(&sleep_time);
    return 0;
}


週期產生的事件都是由系統定時器驅動的。系統定時器是一種可程式設計硬體晶片,它已固定頻率產生中斷。該中斷就是所謂的定時器中斷,它所對應的中斷處理程式負責更新系統時間,還負責執行需要週期性執行的任務。系統定時器和時鐘中斷處理程式是Linux系統核心管理機制中的中樞。

1  核心中的時間概念

硬體為核心提供了一個系統定時器用以計算流逝的時間,系統定時器以某種頻率自行觸發時鐘中斷,該頻率可以通過程式設計預定,稱節拍率。當時鍾中斷髮生時,核心就通過一種特殊中斷處理程式對其進行處理。核心知道連續兩次時鐘中斷的間隔時間。這個間隔時間稱為節拍(tick),核心就是靠這種已知的時鐘中斷來計算牆上時間和系統執行時間。牆上時間即實際時間,該時間放在xtime變數中,核心提供了一組系統呼叫以獲取實際日期和實際時間。系統執行時間——自系統啟動開始所經過的時間——對使用者和核心都很有用,因為許多程式都必須清楚流逝過的時間。

2節拍率

系統定時器頻率是通過靜態預處理定義的,也就是HZ,為一秒內時鐘中斷的次數,在系統啟動時按照Hz對硬體進行設定。體系結構不同,HZ的值也不同。核心在檔案<asm/param.h>中定義了HZ的實際值,節拍率就是HZ,週期為1/HZi386的節拍率為1000,其它體系結構(包括ARM)的節拍率多數都等於100

3   jiffies

全域性變數jiffies用來記錄自系統啟動以來產生的節拍的總數。啟動時,核心將該變數初始化為0,此後,每次時鐘中斷處理程式都會增加該變數的值。因為一秒內時鐘中斷的次數等於Hz,所以jiffes一秒內增加的值也就為Hz,系統執行時間以秒為單位計算,就等於jiffes/HzJiffes=seconds*HZ

Jiffs定義在檔案linux/jiffs.h

Extern unsigned long volatile jiffies

關鍵字volatile指示編譯器在每次訪問變數時都重新從主記憶體中獲得,而不是通過暫存器中的變數別名訪問,從而確保前面的迴圈能按預期的方式執行。

3.1 jiffies的內部表示

       jiffies變數總是無符號長整數(unsigned long),因此,在32位體系結構上是32位,在時鐘頻率為100的情況下,497天后會溢位,如果頻率是100049.7天后會溢位

3.2使用者空間和HZ

2.6以前的核心中,如果改變核心中HZ的值會給使用者空間中某些程式造成異常結果。這是因為核心是以節拍數/秒的形式給使用者空間匯出這個值的,在這個介面穩定了很長一段時間後應用程式便逐漸依賴於這個特定的HZ值了。所以如果在核心中更改了HZ的定義值,就打破了使用者空間的常量關係——使用者空間並不知道新的HZ值。

要想避免上面的錯誤,核心必須更改所有匯出的jiffies值。因而核心定義了USER_HZ來代表使用者空間看到的值。對於ARM體系結構,HZ = USR_HZ

4硬實鍾和定時器

體系結構提供了兩種裝置進行計時——一種是我們前面討論過的系統定時器,另一種是實時時鐘。實時時鐘(RTC)是用來持久存放系統時間的裝置,即便系統關閉後,它可以靠主機板上的微型電池提供的電力保持系統的計時。當系統啟動時,核心通過讀取RTC來初始化牆上時間,該時間存放在xtime變數中。

系統定時器是核心定時機制中最為重要的角色。儘管不同體系結構中的定時器實現不盡相同,但是系統定時器的根本思想沒有區別——提供一種週期性觸發中斷機制。

5時鐘中斷處理程式

下面我們看一下時鐘中斷處理程式是如何實現的。時鐘中斷處理程式可以劃分為兩個部分:體系結構相關部分和體系結構無關部分。

與體系結構相關的例程作為系統定時器的中斷處理程式而註冊到核心中,以便在產生時鐘中斷時,它能夠相應的執行。雖然處理程式的具體工作依賴於特定的體系結構,但是絕大多數處理程式至少要執行如下工作:

1)獲得xtime_lock鎖,以便對訪問jiffies_64和牆上時間xtime進行保護。

2)需要時應答或重新設定系統時鐘。

3)週期性的使用牆上時間更新實時時鐘。

4)呼叫體系結構無關的例程:do_timer

中斷服務程式主要通過呼叫與體系結構無關的例程do_timer執行下面的工作:

jiffies_64變數增加1

更新資源消耗的統計值,比如當前程序所消耗的系統時間和使用者時間。

執行已經到期的動態定時器。

執行scheduler_tick()函式。

更新牆上時間,該時間存放在xtime變數中。

Do_timer()函式執行完畢後返回與體系結構相關的中斷處理程式,繼續執行後面的工作,釋放xtime_lock鎖,然後退出。

以上全部工作每1/HZ秒都要發生一次,也就是說在你的PC機上時鐘中斷處理程式每秒執行1000次。

6實際時間

當前實際時間(牆上時間)定義在檔案kernel/timer.c中:

struct timespec xtime;

timespec資料結構定義在檔案<linux/time.h>中,形式如下:

struct timespec{      time_t   tv_sec;           /* */

                                long tv_nsec;            /*納秒 */

}

其中,xtime.tv_sec以秒為單位,存放著自197071以來經過的時間。xtime.tv_nsec記錄了自上一秒開始經過的納秒數。讀寫xtime變數需要使用xtime_lock鎖,它是一個seq鎖。讀取xtime時要使用read_seqbegin()read_seqretry()函式:



SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
        struct timezone __user *, tz)---》

do_gettimeofday(&ktv);----》

Time.c (kernel\kernel):SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,

SYSCALL_DEFINE2(gettimeofday, struct timeval __user *, tv,
        struct timezone __user *, tz)
{
    if (likely(tv != NULL)) {
        struct timeval ktv;
        do_gettimeofday(&ktv);
        if (copy_to_user(tv, &ktv, sizeof(ktv)))
            return -EFAULT;
    }
    if (unlikely(tz != NULL)) {
        if (copy_to_user(tz, &sys_tz, sizeof(sys_tz)))
            return -EFAULT;
    }
    return 0;
}

Timekeeping.c (kernel\kernel\time):void do_gettimeofday(struct timeval *tv)

void do_gettimeofday(struct timeval *tv)
{
    struct timespec now;

    getnstimeofday(&now);
    tv->tv_sec = now.tv_sec;
    tv->tv_usec = now.tv_nsec/1000;
}

Timekeeping.c (kernel\kernel\time):void getnstimeofday(struct timespec *ts)

void getnstimeofday(struct timespec *ts)
{
    unsigned long seq;
    s64 nsecs;

    WARN_ON(timekeeping_suspended);

    do {
        seq = read_seqbegin(&xtime_lock);

        *ts = xtime;
        nsecs = timekeeping_get_ns();

        /* If arch requires, add in gettimeoffset() */
        nsecs += arch_gettimeoffset();

    } while (read_seqretry(&xtime_lock, seq));

    timespec_add_ns(ts, nsecs);
}

EXPORT_SYMBOL(getnstimeofday);

該迴圈不斷重複,直到讀者確認讀取資料時沒有寫操作介入。如果發現迴圈期間有時鐘中斷處理程式更新xtime,那麼read_seqretry()函式就返回無效序列號,繼續迴圈等待。從使用者空間取得牆上時間的主要介面是gettimeofday()

7  定時器

定時器,有時也稱為動態定時器或核心定時器——是管理核心時間的基礎。定時器的使用很簡單。只需要執行一些初始化工作,設定一個超時時間,指定超時發生後執行的函式,然後啟用定時器就可以了。指定的函式將在定時器到期時自動執行。定時器並不週期執行,它在超時後就自行銷燬,這也正是這種定時器被稱為動態定時器的一個原因。

7.1使用定時器

定時器由結構timer_list表示,定義在檔案<linux/timer.h>中。

struct timer_list {

               struct list_head entry;         /*定時器連結串列的入口 */

                 unsigned long expiers;       /*jiffies為單位的定時器 */

               spinlock_t   lock;                   /*保護定時器的鎖 */

               void   ( * function)(unsigned long);      /*定時器處理函式 */

              unsigned   long   data;            /*傳給處理函式的長整形引數 */

             struct tvec_t_base_s   *base;     /*定時器內部值,使用者不要使用 */

}

核心提供了一組與定時器相關的介面用來簡化管理定時器的操作。所有這些介面都宣告在檔案<linux/timer.h>中,大多數介面都在kernel/timer.c中獲得實現。

建立定時器時需要先定義它: struct   timer_list   my_timer;

初始化定時器資料結構,初始化必須在使用其它定時器管理函式對定時器進行操作之前完成。

     init_timer(&my_timer);   然後就可以填充結構中需要的值了。

    my_timer.expires = jiffies + delay;          /*定時器超時時的節拍數 */

    my_timer.data = 0;                                /*給定時器處理函式傳入0 */

    my_timer.function = my_function;          /*定時器超時時呼叫的函式 */

     my_timer.expires表示超時時間,它是以節拍為單位的絕對計數值。如果當前jiffies計數等於或大於它,處理函式開始執行。處理函式必須符合下面的函式原形:

void   my_timer_function(unsigned long   data);

data引數使我們可以利用一個處理函式註冊多個定時器,只需通過該引數就能區別它們。

啟用定時器:add_timer(&my_timer);

有時可能需要更改已經啟用的定時器超時時間,所以核心通過函式mod_timer()來實現該功能,該函式可以改變指定的定時器超時時間:

mod_timer(&my_timer, jiffies+new_delay);

mod_timer()函式也可以操作那些已經初始化,但還沒有被啟用的定時器,它會同時啟用它。一旦從mod_timer()函式返回,定時器都將被啟用而且設定了新的定時值。

如果需要在定時器超時前停止定時器,可以使用del_timer()函式:

del_timer(&my_timer);        del_timer_sync()(不能在中斷上下文中使用)

8延遲執行

8.1忙等待

最簡單的延遲方法是忙等待(或者說是忙迴圈)。但這種方法僅僅適用於延遲的時間是節拍的整數倍,或者精確度要求不高時。更好的方法是在程式碼等待時,允許核心重新排程執行其他任務:

unsigned long   delay = jiffies + 5*HZ;

while(time_before(jiffies, delay))           cond_resched();

cond_resched()函式將排程一個新程式投入執行,但它只有在設定完need_resched標誌後,才能生效。延遲執行不管在哪種情況下都不應該在持有鎖或禁止中斷時發生。

8.2短延遲

有時核心程式碼(通常也是驅動程式)不但需要很短暫的延遲(比時鐘節拍還短)而且還要求延遲的時間按很精確。這種情況多發生在和硬體同步時,核心提供了兩個可以處理微秒和毫秒級別的延遲函式,它們都定義在<linux/delay.h>中,可以看到它們並不使用jiffies:

void udelay(unsigned long usecs)

void mdelay(unsigned long msecs)

經驗證明,不要使用udelay()函式處理超過1毫秒的延遲。此時使用mdelay()更為安全。

納秒,微妙,毫 秒延遲,必須是短延遲,時間過長會報錯

標頭檔案: delay.h

void ndelay(unsigned long nesec);

void udelay(unsigned long usecs);

void mdelay(unsigned long msecs);

void msleep(unsigned int millisecs);

void ssleep(unsigned int seconds);


長延遲

標頭檔案:jeffies.h / time.h

while(time_before(jiffies,jiffies+msecs_to_jiffies(delay_time)){

              schedule();

}


8.3 schedule_timeout()

更理想的延遲執行方法是使用schedule_timeout()

相關推薦

Linux核心時間管理定時

轉自:http://blog.csdn.net/zhenwenxian/article/details/7643742 時間管理在核心中佔有非常重要的地位。相對於事件驅動,核心中有大量的函式都是基於時間驅動的。核心必須管理系統的執行時間以及當前的日期和時間。 首先搞

linux核心設計與實現 —— 定時時間管理(第11章)

核心中的時間概念 硬體為核心提供了一個系統定時器用以計算流逝的時間。系統定時器是一種可程式設計硬體晶片,它能以固定頻率產生中斷。該頻率可以通過程式設計預定,稱作節拍率(tick rate)。該中斷就是所謂的定時器中斷,它所對應的中斷處理程式負責更新系統時間,也

linux下c/c++例項之六時間測試定時

一、簡介       Linux中使用sleep會導致程式一直阻塞,無法互動,同時sleep和usleep有時也不精確,在此總結linux下的部分時間操作。 二、詳解 1、程式碼timer.cpp #include <iostream> #include &

Linux深度攻略》一書,講述Linux日常系統管理服務配置內容

linuxLinux深度攻略 首先從介紹Linux系統的安裝入手,講述了Linux系統管理和服務器配置兩部分的知識。系統管理方面內容有Linux系統簡介和安裝,Linux字符界面,目錄和文件管理,Linux常用命令,Shell編程,用戶和組群賬戶管理,權限、所有者和ACL,歸檔、壓縮和備份,軟件包管理,磁盤和

linux核心分析之軟定時筆記

定時器是一種軟體功能,即允許在將來的某個時刻,函式在給定的時間間隔用完時被呼叫。超時表示與定時器相關的時間間隔已經用完的那個時刻。 linux上考慮兩種型別的定時器,即動態定時和間隔定時器。第一種型別由核心使用,而間隔定時器由程序在使用者態建立。 動態定時器 動態定時的主要

Linux核心時間管理子系統——時鐘源

struct clocksource { /* * Hotpath data, fits in a single cache line when the * clocksource itself is cacheline aligned.

Linux核心時間管理相關的介面

在核心經常會碰到一些要定時排程的任務,可以用timer處理,下面來看看都有哪些介面, /*******************************************************************/ linux/param.h HZ;//巨集,每

[linux]linux核心時間管理基礎

一,linux時間管理基礎http://blog.csdn.net/droidphone/article/details/7975694http://blog.csdn.net/smilingjames/article/details/6205540 linux所有時間基礎

linux時間定時zz

一段時間 納秒 target 程序 set 不能 ive thread 微秒 https://www.cnblogs.com/cobbliu/p/3627061.html Linux 的計時函數,用於獲得當前時間: time(2) / time_t (秒) ftime(3

表單時間定時

1.針對表單的 form 表單  input 輸入框 select 下拉列表  textarea 文字域 type 型別 radio 單選框 checkbox 多選框 password 密碼框 button 普通按鈕 text 文字框標籤 submit 提交按鈕 rese

北京代孕 表單時間定時this的指向

北京代孕█微信:138-0226-9370██████代孕包成功電詢顧問,代孕包男孩,供卵代孕,三代試管嬰兒選性別,供卵試管嬰兒,十年老品牌代孕公司, 表單時間和定時器this的指向 1.針對表單的 form 表單  input 輸入框 select 下拉列表 

深圳代孕多少 表單時間定時this的指向

深圳代孕多少█微信:138-0226-9370██████代孕包成功電詢顧問,代孕包男孩,供卵代孕,三代試管嬰兒選性別,供卵試管嬰兒,十年老品牌代孕公司, 表單時間和定時器this的指向 1.針對表單的 form 表單  input 輸入框 select 下拉列表&nb

北京代孕(必看介紹) 表單時間定時this的指向

北京代孕█微信:138-0226-9370██████代孕包成功電詢顧問,代孕包男孩,供卵代孕,三代試管嬰兒選性別,供卵試管嬰兒,十年老品牌代孕公司, 表單時間和定時器this的指向 1.針對表單的 form 表單  input 輸入框 select 下拉列表 

linux應用程式中的延時定時

筆記:在linux應用程式中延時有sleep()、msleep()和usleep()函式之類的延時,也有如下形式的延時: struct timeval delay; delay.tv_sec = sleepSecond; delay.tv_usec =

嵌入式Linux開發——(六)系統時鐘定時

一、系統時鐘和定時器 1)S3C2440 / S3C2410時鐘體系     ①3種時鐘:         A、FCLK: 用於CPU         B、HCLK: 用於AHB總線上裝置,比如CPU核、儲存控制器、中斷控制器、LCD控 制器、DMA和USB主機模組等

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

1.日期時間輸出格式: printf("%04d-%02d-%02d\n",year,month,day); 輸出:1994-02-07  d表示輸出整數、2表示寬度、0表示不足兩位前面補0,右對齊。 2.signal函式: signal(SIGALRM,statis

linux軟件管理(Vim編輯使用) ——(七)

切換 顯示 檢查 hive vim編輯器使用 中心 open 互聯網 下載 windows : .exe 安裝 、卸載 安裝: mysql.exe cc.exe 卸載 : 該軟件唯一的標識 ,包名 alibaba

Android零基礎入門第60節:日歷視圖CalendarView定時Chronometer

獲取 studio num check 結構 如果 list switcher nag 上一期學習了AnalogClock、DigitalClock和TextClock時鐘組件,本期繼續來學習日歷視圖CalendarView和定時器Chronometer。

利用定時 1定時0控制led1led2分別 2hz0.5hz閃爍

fine blog style 0ms log pre del nbsp efi 1 //利用定時器 1和定時器0控制led1和led2分別 2hz和0.5hz閃爍 2 //利用定時器0 1s,led1取反,利用計數器1,(65535-10)%256,取反 3 #i

Linux之組管理許可權管理【重點】

一、Linux組基本介紹 在linux中的每個使用者必須屬於一個組,不能獨立於組外。在linux中每個檔案 有所有者、所在組、其它組的概念。 1) 所有者 2) 所在組 3) 其它組 4) 改變使用者所在的組 示意圖如下: 二、檔案/目錄 所有者 一般為檔案的