1. 程式人生 > >使用者級執行緒和核心級執行緒0

使用者級執行緒和核心級執行緒0

轉自:http://www.2ndmoon.net/weblog/?p=603

一、linux 程序/執行緒基礎

        程序是系統中程式執行和資源分配的最小單位。每個程序都擁有自己的資料段,程式碼段和堆疊段。這就造成了程序在進行切換等操作時需要有比較負責的上下文切換等動作。為了進一步減少處理機的空轉時間,支援多處理器,和減少上下文開銷,由此有執行緒的提出。

執行緒是程序內的一種基本排程單位,也可以稱作輕量級程序。執行緒是在共享記憶體空間中併發的多道執行路徑,它們共享一個程序的資源,如檔案描述符,訊號處理。從而大大減少了上下文切換的花銷。同進程一樣,執行緒也將相關的變數值放線上程控制表內,一個程序有多個執行緒,但卻共享一個使用者地址空間,這樣同步的問題顯得非常重要。

執行緒按照排程者可以分為使用者級執行緒和核心級(核心級)執行緒。

使用者級執行緒:排程演算法和排程過程有使用者自行決定,缺點在於,如果一個程序中的某一個執行緒呼叫一個阻塞的系統呼叫,則該程序中的其他執行緒也會被阻塞。這樣就在一個程序中的多個執行緒的排程無法發揮出多處理器的優勢。

核心級(核心級)執行緒: 這個執行緒允許不同程序中的執行緒按照同一個相對優先排程方法進行排程,這樣就能發揮出多處理器的併發優勢。

二、linux 使用者執行緒和核心執行緒

1.linux 使用者執行緒

2.linux 核心執行緒

(1)核心執行緒

       Linux核心在完成初始之後,會把控制權交給應用程式。只有當硬體中斷、軟中斷、異常等發生時,CPU才會從使用者空間切換到核心空間來執行相應的處理,完成後又回來使用者空間。

       如果核心需要週期性地做一些事情(比如頁面的換入換出,磁碟快取記憶體的重新整理等),又該怎麼辦呢?核心執行緒(核心程序)可以解決這個問題。

       核心執行緒(kernel thread)是由核心自己建立的執行緒,也叫做守護執行緒(deamon)。在終端上用命令”ps -Al”列出的所有程序中,名字以k開關以d結尾的往往都是核心執行緒,比如kthreadd、kswapd。

(2)核心執行緒的特點

核心執行緒與使用者執行緒的相同點是:

  • 都由do_fork()建立,每個執行緒都有獨立的task_struct 和核心棧;
  • 都參與排程,核心執行緒也有優先順序,會被排程器平等地換入換出。

不同之處在於:

  • 核心執行緒只工作在核心態中;而使用者執行緒則既可以執行在核心態,也可以執行在使用者態;
  • 核心執行緒沒有使用者空間,所以對於一個核心執行緒來說,它的0~3G的記憶體空間是空白的,它的current->mm是空的,與核心使用同一張頁表;而使用者執行緒則可以看到完整的0~4G記憶體空間。

(3)核心執行緒的建立

        在Linux核心啟動的最後階段,系統(“啟動”核心程序:PID為0的程序)會建立兩個核心執行緒,一個是init,一個是kthreadd。

        具體的講,核心初始化工作的最後一部分是在函式rest_init()中完成的。在這個函式中,主要做了4件事情,分別是:建立init執行緒,建立kthreadd執行緒,執行schedule()開始排程,執行cpu_idle()讓CPU進入idle狀態。經過簡化的程式碼如下:

<span style="font-size:18px;">static noinline void __init_refok rest_init(void)
 __releases(kernel_lock)
{
 kernel_thread(kernel_init, NULL, CLONE_FS | CLONE_SIGHAND);
 pid = kernel_thread(kthreadd, NULL, CLONE_FS | CLONE_FILES);
 schedule();
 cpu_idle();
}</span>

在核心執行緒建立過程中還有兩個有趣的細節值得說一下:

  1. 雖然init執行緒是在kthreadd之前建立的,pid也比較小,但是在schedule()的時候,最先被選中先執行的是kthreadd。這不會有任何影響,因為kthreadd總會讓出CPU,init 執行緒一定能啟動。
  2. 程序號PID的分配是從0開始的,但是在”ps”命令中看不到0號程序。這是因為0號pid被分給了“啟動”核心程序,就是完成了系統引導工作的那個程序。在函式rest_init()中,0號程序在建立完成了init和kthreadd兩個核心執行緒之後,呼叫schedule()使得pid=1和2的兩個執行緒得以啟動,但是pid=0的執行緒並不參與排程,所以這個程序就再也得不到運行了。如下所示,在我們前面已經看到過的這段程式碼中,schedule()不會返回,最後一行的cpu_idle()其實是不會被執行到的
  3. 在init執行緒中,將執行完”/sbin/init”、”/etc/init”和”/bin/init”三個指令碼,並啟動shell。run_init_process(“/bin/sh”)並不會返回,init 執行緒就停在這裡,以後所有的應用程式程序都將從/bin/sh克隆,而sh來自init核心執行緒,所以init執行緒最終成為所有使用者程序的祖先。

通過命令列檢視可以看出程序的ID:

        [email protected]:~$ ps -ef
        UID        PID  PPID  C STIME TTY          TIME  CMD
        root         1     0         0 08:12    ?        00:00:01   /sbin/init    ////第1個核心執行緒(父程序ID:0-“啟動”核心程序)
        root         2     0         0 08:12    ?        00:00:00   [kthreadd] ////第2個核心執行緒(父程序ID:0-“啟動”核心程序)


         其中init執行緒的作用是執行檔案系統上的一系列”init”指令碼,並啟動shell程序,所以init執行緒稱得上是系統中所有使用者程序的祖先,它的pid是1。kthreadd 執行緒是核心的守護執行緒,在核心正常工作時,它永遠不退出,是一個死迴圈,它的pid是2。

相關推薦

使用者執行核心執行0

轉自:http://www.2ndmoon.net/weblog/?p=603 一、linux 程序/執行緒基礎         程序是系統中程式執行和資源分配的最小單位。每個程序都擁有自己的資料段,程式碼段和堆疊段。這就造成了程序在進行切換等操作時需要有比較負責的上下

使用者執行核心執行,你分得清嗎?

這篇文章是上一篇部落格的補充,旨在把沒有講清楚的「使用者級執行緒和核心級執行緒」補充完整。希望讀者能對執行緒有更進一步的瞭解。 小白最近在學習多執行緒程式設計。 網上關於多執行緒的資料很多,小白很快就把執行緒的基本概念弄懂了,但關於「使用者級執行緒和核心級執行緒」的概念,她卻怎麼也搞不清楚,只好向作業系統基

使用者執行核心執行硬體執行

在閱讀<<作業系統概念>>一書中多次提到使用者執行緒、核心執行緒、以及硬體執行緒、軟體執行緒、 我們來解釋這些概念的不同。   1.使用者級執行緒在使用者層通過執行緒庫來實現。對它的建立,撤銷和切換都不利用系統的呼叫。 2.核心級執行緒由作業系統

核心執行 使用者執行

  從執行緒實現的角度看,執行緒可以分成使用者級執行緒,核心級執行緒和輕量級執行緒。   在核心級執行緒的實現中,執行緒管理的所有工作由作業系統核心來做,核心專門提供API供開發者使用,應用程式區不需要有執行緒管理的程式碼。核心級執行緒的優點:在多處理器上,核心能排程同

使用者執行核心執行

1、使用者級執行緒 把整個執行緒實現部分放在使用者空間中,核心對執行緒一無所知,核心看到的就是一個單執行緒程序。 只有一個使用者棧 優點: 1)整個使用者級執行緒的切換髮生在使用者空間,這樣的執行緒切換至少比陷入核心要快一個數量級

Java多執行程式設計核心技術 —— 執行間通訊

執行緒是作業系統中獨立的個體,但這些個體如果不經過特殊的處理就不能成為一個整體。執行緒間的通訊就是成為整體的比用方案之一,可以說,使執行緒間進行通訊後,系統之間的互動性會更強大,在大大提高CPU利用率的同時還會使程式設計師對個執行緒任務在處理的過程中進行有效的把控與監督。 1、

Java(三)併發控制5.繼承建立執行實現建立執行之間的區別

這是使用繼承建立的執行緒 class Person extends Thread { private int num=50; public Person(String name) { super(name); } public void run()

Java的守護執行非守護執行

一、守護執行緒         java分為兩種執行緒:使用者執行緒和守護執行緒         守護執行緒是指在程式執行的時候在後臺提供一種通用服務的執行緒,比如垃圾回收執行緒就是一個很稱職的守護者,並且這種執

VS2010/MFC入門程式設計十七(多執行的建立,包括工作執行使用者介面執行

1.MFC多執行緒簡介 MFC對多執行緒進行了一層簡單的封裝,在Visual C++中每個執行緒都是從CWinThread類繼承而來的。每一個應用程式的執行都有一個主執行緒,這個主執行緒也是從CWinThread類繼承而來的。可以利用CWinThread物件建立應用程式執行的其它執行緒。 MFC用CW

MFC:多執行網路多執行程式設計舉例

<span style="font-size:14px;"> <span style="white-space:pre"> </span>多執行緒程式設計簡例: HANDLE CreateThread( LPS

java守護執行非守護執行

Java 執行緒分為兩類:使用者執行緒(User Thread)和守護執行緒(Daemon Thread) 守護執行緒的作用是為其他執行緒提供服務,譬如垃圾回收器(GC),只要當前 JVM 例項中還有非守護執行緒執行,則守護執行緒就會一直工作下去,直至所有非守護執行緒結束,

Linux程序核心程序的一些知識

理想情況下,您應該明白在您的系統中執行的每一個程序。要獲得所有程序的列表,可以執行命令ps -ef(POSIX 風格)或 ps ax(BSD 風格)。程序名有方括號的是核心級的程序,執行輔助功能(比如將快取寫入到磁碟);所有其他程序都是使用者程序。您會注意到,就算是在

WPF利用Interactive Data Display實現示波器(C#多執行WPF多執行

2018.8.7(已實現) 首先,今天還沒有實現示波器,專案中需要這個功能,在探索中有了一點進展,先記錄下來。 實現的chart控制元件,能夠相應滑輪、滑鼠拖動、放大縮小,很適合作為示波器的背景。 關於Interactive Data Display的引用,可以考慮

Android UI執行非UI執行

public void onClick(View v) { new Thread(new Runnable() { public void run() { final Bitmap bitmap = loadImageFromNetwork("http://

Java 多執行:守護執行非守護執行

本文內容大多基於官方文件和網上前輩經驗總結,經過個人實踐加以整理積累,僅供參考。 Java 執行緒分為兩類:使用者執行緒(User Thread)和守護執行緒(Daemon Thread) 守護執行緒的作用是為其他執行緒提供服務,譬如垃圾回收器(GC),

java多執行_守護執行非守護執行

基本概念 守護執行緒:和主執行緒一起結束的執行緒,叫守護執行緒。 非守護執行緒:主執行緒的結束不影響執行緒的執行的執行緒,也叫使用者執行緒。 如何將一個執行緒t變成守護執行緒 呼叫t.setDaemon(true)方法將非守護執行緒變為守護執行緒。

Solaris10 下的多執行Mysql多執行連線

1. Solairs下的多執行緒 執行緒分成兩種,一種是POSIX格式的(使用 pthread.h),一種是Solairs格式的(thread.h),建議使用 POSIX格式。 int pthread_create(pthread_t *restrict th

5.UI執行非UI執行的互動方式

  一般來說有三種方式:      1.Activity.unOnUiThread(Runnable)      如果當前執行緒是UI Thread,立馬執行action.run方法;否則將Runnable傳送到UI Thread的event 佇列中。    

程序員程序員的區別

工程 文章 忽略 自己 而不是 公司 .com 事物 mpi 低級程序員認為自己與高級程序員的區別, 主要是高級程序員任何功能都能編碼實現, 編碼速度快, 代碼無 bug. 正如一慣的那樣, 低級程序員之所以低級, 正是因為他們勉強能看到(或者根本看不到)事物的表象而看不到

【js】用js定時迴圈執行語句定時延緩執行

        最近在專案中,需要使用到站內信的訊息推送方式在網站中給使用者推送訊息,就是在頁面有下角推送一個彈窗,這裡需要我們定時去後臺查詢是否有訊息推送過來,所以需要在JS層面進行定時執行查詢的任務。 這裡用到了JS的兩個函式方法,一個是setInterval,一個是setT