线程和进程之间的联系----基本概念
什么是線程?
在回答這個問題之前先得要回答進程,
傳統操作系統上進程是 pcb,操作系統通過pcb控制程序運行;但是在 linux 下線程使用 pcb 實現調度,linux下 pcb 是線程,也叫輕量級進程,同一個進程中的線程共同使用一個虛擬地址空間,進程也就變成了線程組;
線程從概念上講,程序里的執行路線,或者說是 “一個進程內部的控制序列” 一切進程至少都有一個執行線程;
線程在進程內部運行,本質是在進程地址空間內運行;
在Linux系統中,在CPU眼中,看到的PCB都要比傳統的進程更加輕量化,透過進程虛擬地址空間,可以看到進程的大部分資源合理分配給每個執行流,就形成了線程執行流
進程和線程的區別?
線程是 CPU 調度基本單位 進程是資源分配單位
進程是 CPU 資源分配的基本單位 —— 資源是分配給線程組的;進程偏向于資源的管理(管理內存,打開的文件…);
線程是 CPU 調度的基本的單位 —— cpu 調度通過 pcb 來調度程序的運行;而線程偏向于調度的執行(調度和進程類似,強占式調度)
在 linux 中把線程叫輕量級進程(LWP), linux 下pcb 是線程 進程是線程組
在window 中進程和線程的關系就不可以說輕量級
線程(優點) VS 進程
線程之間共享一塊虛擬地址空間,進程的虛擬地址空間不共享,
創建、銷毀一個線程要比進程花費的代價更小,因為在創建的時候不會創見虛擬地址空間,和進程共享一塊虛擬地址空間;
線程間的切換工作量小,切換調度的開銷小
線程占用的資源更小
線程(缺點) VS 進程
健壯性降低:一個線程異常終止,會導致進程異常終止,也就是說線程之間是缺乏保護的;
編程 / 調試難度變大:(a)對線程的可靠性要求更高(b)線程安全問題
線程之間的共用資源
虛擬地址空間:由于共享地址空間,那么代碼段、數據段也同樣是共享的
文件描述符表
信號處理方式
當前工作路徑
用戶id 、組 id
…
線程之間獨立不共用的資源
棧(函數調用棧,局部變量等)
上下文信息(CPU中的寄存器)
errno(每個線程有自己的errno)
線程標識符
信號屏蔽字
…
【參考】https://blog.csdn.net/u014558484/article/details/52550678/
多線程/多進程的應用場景
CPU密集型
https://blog.csdn.net/youanyyou/article/details/78990156
IO密集型
通過網絡進程輸入輸出
響應UI界面(界面顯示和數據計算要多線程完成,防止由于數據計算太久導致界面卡死)
多線程和多進程使用場景
線程控制相關函數不是系統調用
庫函數-》posix 線程庫 pthread
ps -eLf 查看所有的線程:站在內核角度給pcb加了一個編號
獲取自己的線程id pthread_self():站在POSIX線程庫的角度
結束線程
讓線程入口函數執行結束,從線程函數中return ;但是在主線程中不能使用return 因為那樣就相當于調用exit
調用 pthread_exit () 終止當前線程,參數是 void* 表示線程結束返回的結果
pthread_cancle (tid) 結束當前進程中的任何一個線程(不推介使用)應為該函數不具有原子性
事物要求具有原子性,打個比方就是:做一件事要么做完,要么就不做,不可以做一半;而這個函數并不具有原性
需要注意的是:pthread_exit 或者 return 返回的指針所指向的內存單元必須是全局的或者是用 malloc 分配的,不能在線程函數的棧上分配,因為當其它線程得到這個返回指針時線程函數已經退出了。
等待線程
為什么要有線程等待:(1)已經退出的線程,其空間沒有被釋放,仍然在進程的地址空間內。(2)創建新的線程不會復用剛才退出線程的地址空間。
目的和進程類型,防止出現類型與僵尸進程的內存泄露的情況
pthread_join (tid,NULL);阻塞函數,等待對應線程結束,然后再繼續執行代碼
線程分離
類似于忽略 SIG_CHLD 信號;
pthread_detach 當線程被分離之后就不需要pthread_join 顯示回收了
默認情況下,新創建的線程是joinable的,線程退出后,需要對其進行pthread_join操作,否則無法釋放資源,從而造成系統泄漏。如果不關心線程的返回值,join是一種負擔,這個時候,我們可以告訴系統,當線程退出時,自動釋放線程資源。
以下僅供了解
線程、用戶態線程、輕量級進程、進程
內核線程
相當于內核可以處理一件特定事情,如:處理異步事件 異步IO (同步和異步區別) 時特別有用 ;內核線程唯一 使用的資源就是內核棧和上下文切換時保存寄存器的空間。支持多線程的內核叫做多線程內核(Multi-Threads kernel )。
內核線程只運行在內核態,不受用戶態上下文的拖累。
處理器競爭:可以在全系統范圍內競爭處理器資源;
調度:調度的開銷可能和進程自身差不多昂貴
同步效率:資源的同步和數據共享比整個進程的數據同步和共享要低一些。
輕量級進程
(LWP) 由內核支持的用戶線程,每一個輕量級進程都與一個特定的內核線程關聯 內核線程只能由內核管理并像普通進程一樣被調度
處理器競爭:因與特定內核線程關聯,因此可以在全系統范圍內競爭處理器資源
使用資源:與父進程共享進程地址空間
調度:像普通進程一樣調度
輕量級線程(LWP)是一種由內核支持的用戶線程。它是基于內核線程的高級抽象,因此只有先支持內核線程,才能有LWP。每一個進程有一個或多個LWPs,每個LWP由一個內核線程支持。在這種實現的操作系統中,LWP就是用戶線程。
由于每個LWP都與一個特定的內核線程關聯,因此每個LWP都是一個獨立的線程調度單元。即使有一個LWP在系統調用中阻塞,也不會影響整個進程的執行。
輕量級進程具有局限性 首先,大多數LWP的操作,如建立、析構以及同步,都需要進行系統調用。系統調用的代價相對較高:需要在用戶態和內核態中切換。其次,每個LWP都需要有一個內核線程支持,因此LWP要消耗內核資源(內核線程的棧空間)。因此一個系統不能支持大量的LWP。
在計算機操作系統中,輕量級進程(LWP)是一種實現多任務的方法。
與普通進程相比:LWP與其他進程共享所有(或大部分)它的邏輯地址空間和系統資源;
與線程相比:LWP有它自己的進程標識符,優先級,狀態,以及棧和局部存儲區,并和其他進程有著父子關系;這是和類Unix操作系統的系統調用vfork()生成的進程一樣的。
線程既可由應用程序管理,又可由內核管理,而 LWP 只能由內核管理并像普通進程一樣被調度;
Linux內核是支持LWP的典型例子。
在大多數系統中,LWP與普通進程的區別也在于它只有一個最小的執行上下文和調度程序所需的統計信息,而這也是它之所以被稱為輕量級的原因;一般來說,一個進程代表程序的一個實例,而LWP代表程序的執行線程(其實,在內核不支持線程的時候,LWP可以很方便地提供線程的實現)。因為一個執行線程不像進程那樣需要那么多狀態信息,所以LWP也不帶有這樣的信息;LWP的一個重要作用是提供了一個用戶級線程實現的中間系統:LWP可以通過系統調用獲得內核提供的服務,因此,當一個用戶級線程運行時,只需要將它連接到一個LWP上便可以具有內核支持線程的所有屬性。缺點:而因為LWP之間共享它們的大部分資源,所以它在某些應用程序就不適用了;這個時候就要使用多個普通的進程了。例如,為了避免內存泄漏和實現特權分隔使用多個進程也使得應用程序在出現進程池內的進程崩潰或被攻擊的情況下變得更加健壯。
用戶線程
完全建立在用戶空間的線程庫,用戶線程的創建、調度、同步和銷毀全由庫函數在用戶空間完成,不需要內核的幫助。因此這種線程是極其低消耗和高效的。
處理器競爭:單純的用戶線程是建立在用戶空間,其對內核是透明的,因此其所屬進程單獨參與處理器的競爭,而進程的所有線程參與競爭該進程的資源。
使用資源:與所屬進程共享進程地址空間和系統資源。
調度:由在用戶空間實現的線程庫,在所屬進程內進行調度
輕量級進程 VS 用戶態線程
LWP雖然本質上屬于用戶線程,但LWP線程庫是建立在內核之上的,LWP的許多操作都要進行系統調用,因此效率不高。
而用戶線程指的是完全建立在用戶空間的線程庫,用戶線程的建立,同步,銷毀,調度完全在用戶空間完成,不需要內核的幫助。因此這種線程的操作是極其快速的且低消耗的
【參考文獻】https://blog.csdn.net/gatieme/article/details/51481863
---------------------?
作者:M-aaron?
來源:CSDN?
原文:https://blog.csdn.net/qq_43763344/article/details/91388328?
版權聲明:本文為博主原創文章,轉載請附上博文鏈接!
總結
以上是生活随笔為你收集整理的线程和进程之间的联系----基本概念的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 银行贷款基准利率2018
- 下一篇: 北京地铁支持支付宝吗