1、進程的信號與信號量通信有什麼區別?
信號量在進程是以有名信號量進行通信的,在線程是以無名信號進行通信的,因為線程linux還沒有實現進程間的通信,所以在sem_init的第二個參數要為0,而且在多線程間的同步是可以通過有名信號量也可通過無名信號,但是一般情況線程的同步是無名信號量,無名信號量使用簡單,而且sem_t存儲在進程空間中,有名信號量必須LINUX內核管理,由內核結構struct
ipc_ids 存儲,是隨內核持續的,系統關閉,信號量則刪除,當然也可以顯示刪除,通過系統調用刪除,
消息隊列,信號量,內存共享,這幾個都是一樣的原理。,只不過信號量分為有名與無名
2、進程間和線程間的協作區別在哪?為什麼需要內核實現通信與同步
進程間和線程間的協作區別:
進程互斥、同步的概念
進程互斥、同步的概念是並發進程下存在的概念,有了並發進程,就產生了資源的競爭與協作,從而就要通過進程的互斥、同步、通信來解決資源的競爭與協作問題。
下面是根據《操作系統教程》3.1.4 中的介紹,整理的進程互斥、同步的概念。
在多道程序設計系統中,同一時刻可能有許多進程,這些進程之間存在兩種基本關系:競爭關系和協作關系。
進程的互斥、同步、通信都是基於這兩種基本關系而存在的,為了解決進程間競爭關系(間接制約關系)而引入進程互斥;為了解決進程間鬆散的協作關系( 直接制約關系)而引入進程同步;為了解決進程間緊密的協作關系而引入進程通信。
第一種是競爭關系
系統中的多個進程之間彼此無關,它們並不知道其他進程的存在,並且也不受其他進程執行的影響。例如,批處理系統中建立的多個用戶進程, 分時系統中建立的多個終端進程。由於這些進程共用了一套計算機系統資源,因而, 必然要出現多個進程競爭資源的問題。當多個進程競爭共享硬設備、存儲器、處理器 和文件等資源時,操作系統必須協調好進程對資源的爭用。
資源競爭出現了兩個控制問題:一個是死鎖 (deadlock )問題,一組進程如果都獲得了部分資源,還想要得到其他進程所佔有的資源,最終所有的進程將陷入死鎖。另一個是飢餓(starvation )問題,這是指這樣一種情況:一個進程由於其他進程總是優先於它而被無限期拖延。
操作系統需要保證諸進程能互斥地訪問臨界資源,既要解決飢餓問題,又要解決死鎖問題。
進程的互斥(mutual exclusion )是解決進程間競爭關系( 間接制約關系) 的手段。 進程互斥指若干個進程要使用同一共享資源時,任何時刻最多允許一個進程去使用,其他要使用該資源的進程必須等待,直到佔有資源的進程釋放該資源。
第二種是協作關系
某些進程為完成同一任務需要分工協作,由於合作的每一個進程都是獨立地以不可預知的速度推進,這就需要相互協作的進程在某些協調點上協 調各自的工作。當合作進程中的一個到達協調點後,在尚未得到其夥伴進程發來的消息或信號之前應阻塞自己,直到其他合作進程發來協調信號或消息後方被喚醒並繼續執行。這種協作進程之間相互等待對方消息或信號的協調關系稱為進程同步。
進程間的協作可以是雙方不知道對方名字的間接協作,例如,通過共享訪問一個緩沖區進行鬆散式協作;也可以是雙方知道對方名字,直接通過通信機制進行緊密協作。允許進程協同工作有利於共享信息、有利於加快計算速度、有利於實現模塊化程序設計。
進程的同步(Synchronization)是解決進程間協作關系( 直接制約關系) 的手段。進程同步指兩個以上進程基於某個條件來協調它們的活動。一個進程的執行依賴於另一
個協作進程的消息或信號,當一個進程沒有得到來自於另一個進程的消息或信號時則需等待,直到消息或信號到達才被喚醒。
不難看出,進程互斥關系是一種特殊的進程同步關系,即逐次使用互斥共享資源,也是對進程使用資源次序上的一種協調。
進程通信的概念
下面是根據《操作系統教程》3.5 中的介紹,整理的進程通信的概念。
並發進程之間的交互必須滿足兩個基本要求:同步和通信。
進程競爭資源時要實施互斥,互斥是一種特殊的同步,實質上需要解決好進程同步問題,進程同步是一種進程通信,通過修改信號量,進程之間可建立起聯系,相互協調運行和協同工作。但是信號量與PV操作只能傳遞信號,沒有傳遞數據的能力。有些情況下進程之間交換的信息量雖很少,例如,僅僅交換某個狀態信息,但很多情況下進程之間需要交換大批數據,例如,傳送一批信息或整個文件,這可以通過一種新的通信機制來完成,進程之間互相交換信息的工作稱之為進程通信IPC (InterProcess Communication)(主要是指大量數據的交換)。進程間通信的方式很多,包括:
信號(signal )通信機制;
信號量及其原語操作(PV、讀寫鎖、管程)控制的共享存儲區(shared memory )通信機制;
管道(pipeline)提供的共享文件(shared file)通信機制;
信箱和發信/ 收信原語的消息傳遞(message passing )通信機制。
其中前兩種通信方式由於交換的信息量少且效率低下,故稱為低級通信機制,相應地可把發信號/ 收信號及PV之類操作稱為低級通信原語,僅適用於集中式操作系統。消息傳遞機制屬於高級通信機制,共享文件通信機制是消息傳遞機制的變種,這兩種通信機制,既適用於集中式操作系統,又適用於分布式操作系統。
進程同步的方法
前面提到,進程互斥關系是一種特殊的進程同步關系,下面給出常見的進程同步的方法,實際上也可用於進程的互斥(個人理解)。
在何炎祥的《計算機操作系統》 3.2 節,將進程同步的機制與解決進程互斥方法看做是一樣的,的明確指出互斥的軟體解決方法為Dekker演算法與Peterson演算法,互斥的硬體解決方法為中斷方法、以及使用機器指令的方法,後面又給出了信號量、管程、消息傳遞三種方法。
實際應用中,不同的系統有不同的進程同步方法,CSDN帖子http://bbs.csdn.net/topics/80156687中有一些討論,Linux 與Windows的主要同步、通信機制如下:
Linux 下:
Linux 下常見的進程同步方法有:SysVIPC 的 sem(信號量)、file locking / record locking(通過 fcntl 設定的文件鎖、記錄鎖)、futex(基於共享內存的快速用戶態互斥鎖)。針對線程(pthread)的還有 pthread_mutex 和 pthread_cond(條件變數)。
Linux 下常見的進程通信的方法有 :pipe(管道),FIFO(命名管道),socket(套接字),SysVIPC 的 shm(共享內存)、msg queue(消息隊列),mmap(文件映射)。以前還有 STREAM,不過現在比較少見了(好像)。
Windows下:
在Windwos中,進程同步主要有以下幾種:互斥量、信號量、事件、可等計時器等幾種技術。
在Windows下,進程通信主要有以下幾種:內存映射、管道、消息等,但是內存映射是最基礎的,因為,其他的進程通信手段在內部都是考內存映射來完成的。
線程的同步/通信與進程的同步/通信有區別嗎?
對於該問題,教材上沒有明確的回答,教材上給出的一般是進程而非線程的同步、通信方式。但網路上很多說法將兩者混為一談。根據教材,以及網上的說法,個人的理解為:
同步機制:
信號量、管程、互斥是進程的同步機制,而信號量、互斥也可用於線程的同步,但管程只在進程同步中被用到;
線程的同步除了信號量、互斥外,還有臨界區、事件,沒有看到教材上將這兩種方式作為進程的同步方式;
通信機制:
管道、FIFO、消息隊列、信號量、共享內存是進程的同步機制,教材上沒有線程的通信機制這樣的說法,但可以肯定這幾種方法是進程的通信方式,且其中的信號量既可用於進程的同步,又可用於進程的通信,在網路上還有說可以用於線程同步的。
管道與管程是不同的,管程是進程同步的方式,而管道則是進程通信的方式。
進程的同步/通信
下面是常見的線程之間的同步方式的詳細介紹。
(註:下面轉自網路,下面的同步、通信方式對於進程與線程分的不是很清楚,關於進程還是線程的解釋見上面——線程的同步/通信與進程的同步/通信有區別嗎?)
一、進程/線程間同步機制。
臨界區、互斥區、事件、信號量四種方式
臨界區(Critical Section)、互斥量(Mutex)、信號量(Semaphore)、事件(Event)的區別
1、臨界區:通過對多線程的串列化來訪問公共資源或一段代碼,速度快,適合控制數據訪問。
在任意時刻只允許一個線程對共享資源進行訪問,如果有多個線程試圖訪問公共資源,那麼在有一個線程進入後,其他試圖訪問公共資源的線程將被掛起,並一直等到進入臨界區的線程離開,臨界區在被釋放後,其他線程才可以搶占。
2、互斥量:採用互斥對象機制。
只有擁有互斥對象的線程才有訪問公共資源的許可權,因為互斥對象只有一個,所以能保證公共資源不會同時被多個線程訪問。互斥不僅能實現同一應用程序的公共資源安全共享,還能實現不同應用程序的公共資源安全共享 .互斥量比臨界區復雜。因為使用互斥不僅僅能夠在同一應用程序不同線程中實現資源的安全共享,而且可以在不同應用程序的線程之間實現對資源的安全共享。
3、信號量:它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數目 .
信號量對象對線程的同步方式與前面幾種方法不同,信號允許多個線程同時使用共享資源,這與操作系統中的PV操作相同。它指出了同時訪問共享資源的線程最大數目。它允許多個線程在同一時刻訪問同一資源,但是需要限制在同一時刻訪問此資源的最大線程數目。
PV操作及信號量的概念都是由荷蘭科學家E.W.Dijkstra提出的。信號量S是一個整數,S大於等於零時代表可供並發進程使用的資源實體數,但S小於零時則表示正在等待使用共享資源的進程數。
P操作申請資源:
(1)S減1;
(2)若S減1後仍大於等於零,則進程繼續執行;
(3)若S減1後小於零,則該進程被阻塞後進入與該信號相對應的隊列中,然後轉入進程調度。
V操作 釋放資源:
(1)S加1;
(2)若相加結果大於零,則進程繼續執行;
(3)若相加結果小於等於零,則從該信號的等待隊列中喚醒一個等待進程,然後再返回原進程繼續執行或轉入進程調度。
4、事 件: 通過通知操作的方式來保持線程的同步,還可以方便實現對多個線程的優先順序比較的操作 .
總結:
1. 互斥量與臨界區的作用非常相似,但互斥量是可以命名的,也就是說它可以跨越進程使用。所以創建互斥量需要的資源更多,所以如果只為了在進程內部是用的話使用臨界區會帶來速度上的優勢並能夠減少資源佔用量。因為互斥量是跨進程的互斥量一旦被創建,就可以通過名字打開它。
2. 互斥量(Mutex),信號燈(Semaphore),事件(Event)都可以被跨越進程使用來進行同步數據操作,而其他的對象與數據同步操作無關,但對於進程和線程來講,如果進程和線程在運行狀態則為無信號狀態,在退出後為有信號狀態。所以可以使用WaitForSingleObject來等待進程和線程退出。
3. 通過互斥量可以指定資源被獨占的方式使用,但如果有下面一種情況通過互斥量就無法處理,比如現在一位用戶購買了一份三個並發訪問許可的資料庫系統,可以根據用戶購買的訪問許可數量來決定有多少個線程/進程能同時進行資料庫操作,這時候如果利用互斥量就沒有辦法完成這個要求,信號燈對象可以說是一種資源計數器。
二、進程間通信方式
由於比較容易混淆,我們把進程間通信方法也列在這里做比較。
進程通信也就是所謂的IPC問題,主要是指進程間交換數據的方式。進程通信包括高級通信與低級通信,其中進程同步與互斥屬於低級通信,主要用於插U農地控制信號;高級通信包括三種:共享存儲系統(有的地方稱作共享內存區)、消息傳遞系統(有的地方稱作消息隊列)、管道。
信號量是進程同步與互斥的常用方法,也可以作為低級的進程通信方法,用於傳遞控制信號。
簡而言之,進程間通信方式主要包括管道、FIFO、消息隊列、信號量、共享內存。
1.管道,還有命名管道和非命名管道(即匿名管道)之分,非命名管道(即匿名管道)只能用於父子進程通訊,命名管道可用於非父子進程,命名管道就是FIFO,管道是先進先出的通訊方式
2.消息隊列,是用於兩個進程之間的通訊,首先在一個進程中創建一個消息隊列,然後再往消息隊列中寫數據,而另一個進程則從那個消息隊列中取數據。需要注意的是,消息隊列是用創建文件的方式建立的,如果一個進程向某個消息隊列中寫入了數據之後,另一個進程並沒有取出數據,即使向消息隊列中寫數據的進程已經結束,保存在消息隊列中的數據並沒有消失,也就是說下次再從這個消息隊列讀數據的時候,就是上次的數據!!!!
3.信號量,它與WINDOWS下的信號量是一樣的,所以就不用多說了
4.共享內存,類似於WINDOWS下的DLL中的共享變數,但LINUX下的共享內存區不需要像DLL這樣的東西,只要首先創建一個共享內存區,其它進程按照一定的步驟就能訪問到這個共享內存區中的數據,當然可讀可寫
以上幾種方式的比較:
1.管道:速度慢,容量有限,只有父子進程能通訊
2.FIFO:任何進程間都能通訊,但速度慢
3.消息隊列:容量受到系統限制,且要注意第一次讀的時候,要考慮上一次沒有讀完數據的問題
4.信號量:不能傳遞復雜消息,只能用來同步
5.共享內存區:能夠很容易控制容量,速度快,但要保持同步,比如一個進程在寫的時候,另一個進程要注意讀寫的問題,相當於線程中的線程安全,當然,共享內存區同樣可以用作線程間通訊,不過沒這個必要,線程間本來就已經共享了同一進程內的一塊內存
本質上,信號量是一個計數器,它用來記錄對某個資源(如共享內存)的存取狀況。一般說來,為了獲得共享資源,進程需要執行下列操作:
(1)測試控制該資源的信號量;
(2)若此信號量的值為正,則允許進行使用該資源,進程將進號量減1;
(3)若此信號量為0,則該資源目前不可用,進程進入睡眠狀態,直至信號量值大於0,進程被喚醒,轉入步驟(1);
(4)當進程不再使用一個信號量控制的資源時,信號量值加1,如果此時有進程正在睡眠等待此信號量,則喚醒此進程。
套接字通信並不為Linux所專有,在所有提供了TCP/IP協議棧的操作系統中幾乎都提供了socket,而所有這樣操作系統,對套接字的編程方法幾乎是完全一樣的
三、進程/線程同步機制與進程間通信機制比較
很明顯2者有類似,但是差別很大
同步主要是臨界區、互斥、信號量、事件
進程間通信是管道、內存共享、消息隊列、信號量、socket
共通之處是,信號量和消息(事件)
小結:
進程互斥、同步與通信的關系:進程競爭資源時要實施互斥,互斥是一種特殊的同步,實質上需要解決好進程同步問題,進程同步是一種進程通信,由此看來,進程互斥、同步都可以看做進程的通信;
信號量是進程同步與互斥的常用方法,也可以作為低級的進程通信方法,用於傳遞控制信號;
管道與管程是不同的,管程是進程同步的方式,而管道則是進程通信的方式;
3、linux信號量的問題
sem_init:初始化信號量sem_t,初始化的時候可以指定信號量的初始值,以及是否可以在多進程間共享。
sem_wait:一直阻塞等待直到信號量>0。
sem_timedwait:阻塞等待若干時間直到信號量>0。
sem_post:使信號量加1。
sem_destroy:釋放信號量。和sem_init對應。 答案補充 關於各函數的具體參數請用man查看,如man sem_init可查看該函數的幫助
4、計算機*作系統中,若P、V*作的信號量S初值為2,當前值為-1,則表示有____個等待進程
有1個等待進程。
信號量(Semaphore),是可以用來保證兩個或多個關鍵代碼段不被並發調用。在進入一個關鍵代碼段之前,線程必須獲取一個信號量;一旦該關鍵代碼段完成了,那麼該線程必須釋放信號量。其它想進入該關鍵代碼段的線程必須等待直到第一個線程釋放信號量。
為了完成這個過程,需要創建一個信號量VI,然後將Acquire Semaphore VI以及Release Semaphore VI分別放置在每個關鍵代碼段的首末端。初值為2,表示初始時有兩個可用的資源。現在為-1,就說明這兩個可用資源已經被佔用了,有一個進程還在等待資源。
(4)seminit進程間擴展資料:
對信號量有4種操作(#include<semaphore.h>):
1、 初始化(initialize),也叫做建立(create) int sem_init(sem_t *sem, int pshared, unsigned int value);
2、等信號(wait),也可叫做掛起(suspend)int sem_wait(sem_t *sem);
3、給信號(signal)或發信號(post) int sem_post(sem_t *sem);
4、清理(destroy) int sem_destory(sem_t *sem)。
5、linux 怎麼查 信號量 被進程p住
sem_init:初始化信號量sem_t,初始化的時候可以指定信號量的初始值,以及是否可以在多進程間共享。
sem_wait:一直阻塞等待直到信號量>0。
sem_timedwait:阻塞等待若干時間直到信號量>0。
sem_post:使信號量加1。
sem_destroy:釋放信號量。和sem_init對應。 答案補充 關於各函數的具體參數請用man查看,如man sem_init可查看該函數的幫助
信號量的工作原理
由於信號量只能進行兩種操作等待和發送信號,即P(sv)和V(sv),他們的行為是這樣的:
P(sv):如果sv的值大於零,就給它減1;如果它的值為零,就掛起該進程的執行
V(sv):如果有其他進程因等待sv而被掛起,就讓它恢復運行,如果沒有進程因等待sv而掛起,就給它加1.
舉個例子,就是兩個進程共享信號量sv,一旦其中一個進程執行了P(sv)操作,它將得到信號量,並可以進入臨界區,使sv減1。而第二個進程將被阻止進入臨界區,因為當它試圖執行P(sv)時,sv為0,它會被掛起以等待第一個進程離開臨界區域並執行V(sv)釋放信號量,這時第二個進程就可以恢復執行。
Linux的信號量機制
Linux提供了一組精心設計的信號量介面來對信號進行操作,它們不只是針對二進制信號量,下面將會對這些函數進行介紹,但請注意,這些函數都是用來對成組的信號量值進行操作的。它們聲明在頭文件sys/sem.h中。
6、進程的信號與信號量通信有什麼區別
信號量在進程是以有名信號量進行通信的,在線程是以無名信號進行通信的,因為線程linux還沒有實現進程間的通信,所以在sem_init的第二個參數要為0,而且在多線程間的同步是可以通過有名信號量也可通過無名信號,但是一般情況線程的同步是無名信號量,無名信號量使用簡單,而且sem_t存儲在進程空間中,有名信號量必須LINUX內核管理,由內核結構struct ipc_ids 存儲,是隨內核持續的,系統關閉,信號量則刪除,當然也可以顯示刪除,通過系統調用刪除,消息隊列,信號量,內存共享,這幾個都是一樣的原理。,只不過信號量分為有名與無名
7、sem_init的說明
<