官术网_书友最值得收藏!

4.9 內(nèi)核線程

例如,μLinux內(nèi)核中新線程的建立可以用kernel_thread函數(shù)實(shí)現(xiàn),該函數(shù)在kernel/fork.c中定義:

long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags)

fn:內(nèi)核線程主函數(shù)。

arg:線程主函數(shù)的參數(shù)。

flags:建立線程的標(biāo)志。

內(nèi)核線程函數(shù)通常都調(diào)用daemonize()進(jìn)行后臺化作為一個獨(dú)立的線程運(yùn)行,然后設(shè)置線程的一些參數(shù),如名稱、信號處理等,這不是必要的。之后就進(jìn)入一個死循環(huán),這是線程的主體部分,這個循環(huán)不能一直在運(yùn)行,否則系統(tǒng)就死在這里了。它或者是某種事件驅(qū)動的,在事件到來前是睡眠的,事件到來后喚醒進(jìn)行操作,操作完后繼續(xù)睡眠;或者是定時睡眠,醒后操作完再睡眠;或者加入等待隊列,通過schedule()調(diào)度獲得執(zhí)行時間。總之這個線程不能一直占著MCU。

以下是內(nèi)核線程的一個示例,取自kernel/context.c。

int start_context_thread(void)
{
    static struct completion startup __initdata=COMPLETION_INITIALIZER(startup);
    kernel_thread(context_thread, &startup, CLONE_FS | CLONE_FILES);
    wait_for_completion(&startup);
    return 0;
}
static int context_thread(void *startup)
{
    struct task_struct *curtask=current;
    DECLARE_WAITQUEUE(wait, curtask);
    struct k_sigaction sa;
    daemonize();
    strcpy(curtask->comm, "keventd");
    keventd_running=1;
    keventd_task=curtask;
    spin_lock_irq(&curtask->sigmask_lock);
    siginitsetinv(&curtask->blocked, sigmask(SIGCHLD));
    recalc_sigpending(curtask);
    spin_unlock_irq(&curtask->sigmask_lock);
    complete((struct completion *)startup);
    /* Install a handler so SIGCLD is delivered */
    sa.sa.sa_handler=SIG_IGN;
    sa.sa.sa_flags=0;
    siginitset(&sa.sa.sa_mask, sigmask(SIGCHLD));
    do_sigaction(SIGCHLD, &sa, (struct k_sigaction *)0);
    /*
    * If one of the functions on a task queue re-adds itself
    * to the task queue we call schedule() in state TASK_RUNNING
    */
    for (;;)
     {
        set_task_state(curtask, TASK_INTERRUPTIBLE);
        add_wait_queue(&context_task_wq, &wait);
        if (TQ_ACTIVE(tq_context))
        set_task_state(curtask, TASK_RUNNING);
        schedule();
        remove_wait_queue(&context_task_wq, &wait);
        run_task_queue(&tq_context);
        wake_up(&context_task_done);
        if (signal_pending(curtask))
        {
            while (waitpid(-1, (unsigned int *)0, __WALL|WNOHANG) > 0)
        ;
            spin_lock_irq(&curtask->sigmask_lock);
            flush_signals(curtask);
            recalc_sigpending(curtask);
            spin_unlock_irq(&curtask->sigmask_lock);
        }
    }
}
主站蜘蛛池模板: 梁平县| 江津市| 陕西省| 宿松县| 双柏县| 盐山县| 华安县| 湘阴县| 堆龙德庆县| 长治县| 济南市| 金堂县| 曲松县| 曲麻莱县| 甘谷县| 洛扎县| 六盘水市| 股票| 雷波县| 镇沅| 广西| 潼关县| 色达县| 昌平区| 安多县| 毕节市| 安吉县| 博野县| 琼海市| 漳平市| 康马县| 五台县| 胶南市| 徐汇区| 沭阳县| 额敏县| 信阳市| 廊坊市| 泰宁县| 增城市| 中西区|