進程線程的概念區別

以下內容來自於百度百科和自己的理解:

1進程

進程(Process)的抽象概念是計算機中的程序關於某數據集合上的一次運行活動,是系統進行資源分配和調度的基本單位,是操作系統結構的基礎。程序是指令、數據及其組織形式的描述,進程是程序的實體。通常情況下window下一個exe就是一個進程,android中一個apk就是一個進程(也可以多進程)。

進程的關鍵點:

  • 第一,進程是一個實體。每一個進程都有它自己的地址空間,包括文本區域(text region)、數據區域(data region)和堆棧(stack region)。文本區域存儲處理器執行的代碼;數據區域存儲變量和進程執行期間使用的動態分配的內存;堆棧區域存儲着活動過程調用的指令和本地變量。
  • 第二,進程是一個“執行中的程序”。程序是一個沒有生命的實體,只有處理器賦予程序生命時,它才能成爲一個活動的實體,我們稱其爲進程。

切換
進程切換就是從正在運行的進程中收回處理器,然後再使待運行進程來佔用處理器。
回收就是把進程存放在處理器的寄存器中的中間數據數據被存儲在進程的私有堆棧,從而把處理器的寄存器騰出來讓其他進程使用。
讓進程來佔用處理器就是把存儲的信息恢復到處理器的寄存器中去,並把待運行進程的斷點送入處理器的程序指針PC,於是待運行進程就開始被處理器運行了,也就是這個進程已經佔有處理器的使用權了。

耗時原因:
切換時設計到信息的存儲和讀取,一個進程存儲在處理器各寄存器中的中間數據叫做進程的上下文,所以進程的切換實質上就是被中止運行進程與待運行進程上下文的切換。在進程未佔用處理器時,進程的上下文是存儲在進程的私有堆棧中的。

狀態切換:
在這裏插入圖片描述
進程的三個基本狀態
1)就緒狀態(Ready):
進程已獲得除處理器外的所需資源,等待分配處理器資源;只要分配了處理器進程就可執行。就緒進程可以按多個優先級來劃分隊列。例如,當一個進程由於時間片用完而進入就緒狀態時,排入低優先級隊列;當進程由I/O操作完成而進入就緒狀態時,排入高優先級隊列。
2)運行狀態(Running):
進程佔用處理器資源;處於此狀態的進程的數目小於等於處理器的數目。在沒有其他進程可以執行時(如所有進程都在阻塞狀態),通常會自動執行系統的空閒進程。
3)阻塞狀態(Blocked):
由於進程等待某種條件(如I/O操作或進程同步),在條件滿足之前無法繼續執行。該事件發生前即使把處理器資源分配給該進程,也無法運行。

進程的調度算法包括:
實時系統中:FIFO(First Input First Output,先進先出算法),SJF(Shortest Job First,最短作業優先算法),SRTF(Shortest Remaining Time First,最短剩餘時間優先算法)。
交互式系統中:RR(Round Robin,時間片輪轉算法),HPF(Highest Priority First,最高優先級算法),多級隊列,最短進程優先,保證調度,彩票調度,公平分享調度。

進程間通信方式:
管道(pipe)及有名管道(named pipe),信號(signal),信號量(semaphore),消息隊列(message queue),共享內存(shared memory),套接字(socket)

2 線程

線程:
線程(thread)是進程中的實際運作單位(屬於某個進程),是操作系統能夠進行運算調度的最小單位。一條線程指的是進程中一個單一順序的控制流,一個進程中可以併發多個線程,每條線程並行執行不同的任務。
線程是獨立調度和分派的基本單位,一個進程可以有很多線程,每條線程並行執行不同的任務。同一進程中的多條線程將共享該進程中的全部系統資源,如虛擬地址空間,文件描述符和信號處理等等。但同一進程中的多個線程有各自的調用棧(call stack),自己的寄存器環境(register context),自己的線程本地存儲(thread-local storage)。

線程的狀態:

  • 新線程態(New Thread)
    產生一個Thread對象就生成一個新線程。當線程處於"新線程"狀態時,僅僅是一個空線程對象,它還沒有分配到系統資源。

  • 可運行態(Runnable)(包括運行態)
    start()方法產生運行線程所必須的資源,調度線程執行,並且調用線程的run()方法。在這時線程處於可運行態,如果線程處於Runnable狀態,它也有可能不在運行,這是因爲還有優先級和調度問題。

  • 阻塞/非運行態(Not Runnable):
    當以下事件發生時,線程進入非運行態。
    ①suspend()方法被調用;
    ②sleep()方法被調用;
    ③線程使用wait()來等待條件變量;
    ④線程處於I/O請求的等待。

  • 死亡態(Dead)
    當run()方法返回(線程執行完),或別的線程調用stop()方法,線程進入死亡態。

public enum State {
        /**
         * Thread state for a thread which has not yet started.
         */
        NEW,

        /**
         * Thread state for a runnable thread.  A thread in the runnable
         * state is executing in the Java virtual machine but it may
         * be waiting for other resources from the operating system
         * such as processor.
         */
        RUNNABLE,

        /**
         * Thread state for a thread blocked waiting for a monitor lock.
         * A thread in the blocked state is waiting for a monitor lock
         * to enter a synchronized block/method or
         * reenter a synchronized block/method after calling
         * {@link Object#wait() Object.wait}.
         */
        BLOCKED,

        /**
         * Thread state for a waiting thread.
         * A thread is in the waiting state due to calling one of the
         * following methods:
         * <ul>
         *   <li>{@link Object#wait() Object.wait} with no timeout</li>
         *   <li>{@link #join() Thread.join} with no timeout</li>
         *   <li>{@link LockSupport#park() LockSupport.park}</li>
         * </ul>
         *
         * <p>A thread in the waiting state is waiting for another thread to
         * perform a particular action.
         *
         * For example, a thread that has called <tt>Object.wait()</tt>
         * on an object is waiting for another thread to call
         * <tt>Object.notify()</tt> or <tt>Object.notifyAll()</tt> on
         * that object. A thread that has called <tt>Thread.join()</tt>
         * is waiting for a specified thread to terminate.
         */
        WAITING,

        /**
         * Thread state for a waiting thread with a specified waiting time.
         * A thread is in the timed waiting state due to calling one of
         * the following methods with a specified positive waiting time:
         * <ul>
         *   <li>{@link #sleep Thread.sleep}</li>
         *   <li>{@link Object#wait(long) Object.wait} with timeout</li>
         *   <li>{@link #join(long) Thread.join} with timeout</li>
         *   <li>{@link LockSupport#parkNanos LockSupport.parkNanos}</li>
         *   <li>{@link LockSupport#parkUntil LockSupport.parkUntil}</li>
         * </ul>
         */
        TIMED_WAITING,

        /**
         * Thread state for a terminated thread.
         * The thread has completed execution.
         */
        TERMINATED;
    }

3 進程與線程比較

進程是資源分配的基本單位,也是搶佔處理機的調度單位,它擁有一個完整的虛擬地址空間。當進程發生調度時,不同的進程擁有不同的虛擬地址空間,而同一進程內的不同線程共享同一地址空間。
而線程與資源分配無關,它屬於某一個進程,並與進程內的其他線程一起共享進程的資源。

線程只由相關堆棧(系統棧或用戶棧)寄存器和線程控制表TCB組成。寄存器可被用來存儲線程內的局部變量,但不能存儲其他線程的相關變量。

通常都是把進程作爲分配資源的基本單位,而把線程作爲獨立運行和獨立調度的基本單位。由於線程比進程更小,基本上不擁有系統資源,故對它的調度所付出的開銷就會小得多,能更高效的提高系統內多個程序間併發執行的程度,從而顯著提高系統資源的利用率和吞吐量。

線程與進程的區別總結:
通信:進程間通信IPC,線程間可以直接讀寫進程數據段(如全局變量)來進行通信——需要進程同步和互斥手段的輔助,以保證數據的一致性。
角色方面:在支持線程機制的系統中,進程是系統資源分配的單位,線程是CPU調度的單位。
資源共享方面:進程之間不能共享資源,而線程共享所在進程的地址空間和其它資源。同時線程還有自己的棧和棧指針,程序計數器等寄存器。
獨立性方面:進程有自己獨立的地址空間,而線程沒有,線程必須依賴於進程而存在。
開銷方面:進程切換的開銷較大。線程相對較小。(前面也提到過,引入線程也出於了開銷的考慮。

4 java中的線程

java中可以通過繼承Thread類、實現Runnable接口、實現Callable接口配合FutureTask包裝器來創建Thread線程來實現線程的創建。

Java中,每個線程都有一個調用棧,即使不在程序中創建任何新的線程,線程也在後臺運行着。

一個Java應用總是從main()方法開始運行,mian()方法運行在一個線程內,它被稱爲主線程。

import java.util.concurrent.Callable;
import java.util.concurrent.Executors;
import java.util.concurrent.FutureTask;

public class Demo1 {

	public static void main(String[] args) {
	
		ThreadDemo demo1 = new ThreadDemo();
		demo1.start();
		
		Thread thread2 = new Thread(new RunnableDemo());
		thread2.start();
		
		FutureTask<String> thread3 = new FutureTask<>(new Callable<String>() {

			@Override
			public String call() throws Exception {
			
				return "demo3";
			}
		});
		
		new Thread(thread3).start();
		
		//or  Executors.newSingleThreadExecutor().execute(thread3);
		
		
	}
	
	public static class ThreadDemo extends Thread{
		@Override
		public void run() {
			System.out.print("demo1");
		}
	}
	
	public static class RunnableDemo implements Runnable{
		@Override
		public void run() {
			System.out.print("demo2");
			
		}
	}

}

實現Runnable接口比繼承Thread類更好:
接口避免了單繼承限制,適合共享統一資源。

線程可以設置名字,也可以不設置系統會自動分配,線程的名字可以相同。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章