同步和通訊的目的是一樣的,實(shí)現進(jìn)程間數據共享,同步只是為了做到處理協(xié)同。
共享內存在Win9X平臺上是有的,在NT內核以后就沒(méi)有這一說(shuō)了,因為進(jìn)程地址空間不再有共用部分 Linux :通信就是說(shuō)進(jìn)程之間傳遞數據。常見(jiàn)的方法有 pipe(管道),FIFO(命名管道),socket(套接字),SysVIPC 的 shm(共享內存)、msg queue(消息隊列),mmap(文件映射)。
以前還有 STREAM,不過(guò)現在比較少見(jiàn)了(好像)。 同步的意思是說(shuō),讓不同進(jìn)程能夠在同時(shí)到達一個(gè)已知的特定狀態(tài)之前等待另一方的執行。
Linux 下常見(jiàn)的同步方法有SysVIPC 的 sem(信號量)、file locking / record locking(通過(guò) fcntl 設定的文件鎖、記錄鎖)、futex(基于共享內存的快速用戶(hù)態(tài)互斥鎖)。針對線(xiàn)程(pthread)的還有 pthread_mutex 和 pthread_cond(條件變量)。
除了這些特定的同步對象之外,還有一些同步方法是與通信方法不可分離的,包括:對 pipe/FIFO/socket 和 msg queue 的阻塞等待、對子進(jìn)程退出事件的等待(wait族)、對線(xiàn)程退出時(shí)間的等待(pthread_join) 另外還有一個(gè)不能不提的,就是信號。
進(jìn)程間通信機制 1 文件映射 文件映射(Memory-Mapped Files)能使進(jìn)程把文件內容當作進(jìn)程地址區間一塊內存那樣來(lái)對待。
因此,進(jìn)程不必使用文件I/O操作,只需簡(jiǎn)單的指針操作就可讀取和修改文件的內容。 Win32 API允許多個(gè)進(jìn)程訪(fǎng)問(wèn)同一文件映射對象,各個(gè)進(jìn)程在它自己的地址空間里接收內存的指針。
通過(guò)使用這些指針,不同進(jìn)程就可以讀或修改文件的內容,實(shí)現了對文件中數據的共享。 應用程序有三種方法來(lái)使多個(gè)進(jìn)程共享一個(gè)文件映射對象。
(1)繼承:第一個(gè)進(jìn)程建立文件映射對象,它的子進(jìn)程繼承該對象的句柄。 (2)命名文件映射:第一個(gè)進(jìn)程在建立文件映射對象時(shí)可以給該對象指定一個(gè)名字(可與文件名不同)。
第二個(gè)進(jìn)程可通過(guò)這個(gè)名字打開(kāi)此文件映射對象。另外,第一個(gè)進(jìn)程也可以通過(guò)一些其它IPC機制(有名管道、郵件槽等)把名字傳給第二個(gè)進(jìn)程。
(3)句柄復制:第一個(gè)進(jìn)程建立文件映射對象,然后通過(guò)其它IPC機制(有名管道、郵件槽等)把對象句柄傳遞給第二個(gè)進(jìn)程。第二個(gè)進(jìn)程復制該句柄就取得對該文件映射對象的訪(fǎng)問(wèn)權限。
文件映射是在多個(gè)進(jìn)程間共享數據的非常有效方法,有較好的安全性。但文件映射只能用于本地機器的進(jìn)程之間,不。
進(jìn)程間通信機制 1 文件映射 文件映射(Memory-Mapped Files)能使進(jìn)程把文件內容當作進(jìn)程地址區間一塊內存那樣來(lái)對待。因此,進(jìn)程不必使用文件I/O操作,只需簡(jiǎn)單的指針操作就可讀取和修改文件的內容。
Win32 API允許多個(gè)進(jìn)程訪(fǎng)問(wèn)同一文件映射對象,各個(gè)進(jìn)程在它自己的地址空間里接收內存的指針。通過(guò)使用這些指針,不同進(jìn)程就可以讀或修改文件的內容,實(shí)現了對文件中數據的共享。
應用程序有三種方法來(lái)使多個(gè)進(jìn)程共享一個(gè)文件映射對象。 (1)繼承:第一個(gè)進(jìn)程建立文件映射對象,它的子進(jìn)程繼承該對象的句柄。
(2)命名文件映射:第一個(gè)進(jìn)程在建立文件映射對象時(shí)可以給該對象指定一個(gè)名字(可與文件名不同)。第二個(gè)進(jìn)程可通過(guò)這個(gè)名字打開(kāi)此文件映射對象。
另外,第一個(gè)進(jìn)程也可以通過(guò)一些其它IPC機制(有名管道、郵件槽等)把名字傳給第二個(gè)進(jìn)程。 (3)句柄復制:第一個(gè)進(jìn)程建立文件映射對象,然后通過(guò)其它IPC機制(有名管道、郵件槽等)把對象句柄傳遞給第二個(gè)進(jìn)程。
第二個(gè)進(jìn)程復制該句柄就取得對該文件映射對象的訪(fǎng)問(wèn)權限。 文件映射是在多個(gè)進(jìn)程間共享數據的非常有效方法,有較好的安全性。
但文件映射只能用于本地機器的進(jìn)程之間,不能用于網(wǎng)絡(luò )中,而開(kāi)發(fā)者還必須控制進(jìn)程間的同步。 2 共享內存 Win32 API中共享內存(Shared Memory)實(shí)際就是文件映射的一種特殊情況。
進(jìn)程在創(chuàng )建文件映射對象時(shí)用0xFFFFFFFF來(lái)代替文件句柄(HANDLE),就表示了對應的文件映射對象是從操作系統頁(yè)面文件訪(fǎng)問(wèn)內存,其它進(jìn)程打開(kāi)該文件映射對象就可以訪(fǎng)問(wèn)該內存塊。由于共享內存是用文件映射實(shí)現的,所以它也有較好的安全性,也只能運行于同一計算機上的進(jìn)程之間。
注意點(diǎn): 要控制同步,而且CString、list、arry、map等的collect class都不能安全的使用于共享內存中 不要把擁有虛函數之C++類(lèi)放到共享內存中 不要把CObject派生類(lèi)之MFC對象放到共享內存中 不要使用"point within the shared memory"的指針 不要使用"point outside of the shared memory"的指針 使用"based"指針是安全的,但要小心使用 3 匿名管道 管道(Pipe)是一種具有兩個(gè)端點(diǎn)的通信通道:有一端句柄的進(jìn)程可以和有另一端句柄的進(jìn)程通信。管道可以是單向-一端是只讀的,另一端點(diǎn)是只寫(xiě)的;也可以是雙向的一管道的兩端點(diǎn)既可讀也可寫(xiě)。
匿名管道(Anonymous Pipe)是 在父進(jìn)程和子進(jìn)程之間,或同一父進(jìn)程的兩個(gè)子進(jìn)程之間傳輸數據的無(wú)名字的單向管道。通常由父進(jìn)程創(chuàng )建管道,然后由要通信的子進(jìn)程繼承通道的讀端點(diǎn)句柄或寫(xiě) 端點(diǎn)句柄,然后實(shí)現通信。
父進(jìn)程還可以建立兩個(gè)或更多個(gè)繼承匿名管道讀和寫(xiě)句柄的子進(jìn)程。這些子進(jìn)程可以使用管道直接通信,不需要通過(guò)父進(jìn)程。
匿名管道是單機上實(shí)現子進(jìn)程標準I/O重定向的有效方法,它不能在網(wǎng)上使用,也不能用于兩個(gè)不相關(guān)的進(jìn)程之間。 4 命名管道 命名管道(Named Pipe)是服務(wù)器進(jìn)程和一個(gè)或多個(gè)客戶(hù)進(jìn)程之間通信的單向或雙向管道。
不同于匿名管道的是命名管道可以在不相關(guān)的進(jìn)程之間和不同計算機之間使用,服務(wù)器建立命名管道時(shí)給它指定一個(gè)名字,任何進(jìn)程都可以通過(guò)該名字打開(kāi)管道的另一端,根據給定的權限和服務(wù)器進(jìn)程通信。 命名管道提供了相對簡(jiǎn)單的編程接口,使通過(guò)網(wǎng)絡(luò )傳輸數據并不比同一計算機上兩進(jìn)程之間通信更困難,不過(guò)如果要同時(shí)和多個(gè)進(jìn)程通信它就力不從心了。
5 郵件槽 郵件槽(Mailslots)提 供進(jìn)程間單向通信能力,任何進(jìn)程都能建立郵件槽成為郵件槽服務(wù)器。其它進(jìn)程,稱(chēng)為郵件槽客戶(hù),可以通過(guò)郵件槽的名字給郵件槽服務(wù)器進(jìn)程發(fā)送消息。
進(jìn)來(lái)的消 息一直放在郵件槽中,直到服務(wù)器進(jìn)程讀取它為止。一個(gè)進(jìn)程既可以是郵件槽服務(wù)器也可以是郵件槽客戶(hù),因此可建立多個(gè)郵件槽實(shí)現進(jìn)程間的雙向通信。
通過(guò)郵件槽可以給本地計算機上的郵件槽、其它計算機上的郵件槽或指定網(wǎng)絡(luò )區域中所。
現在最常用的進(jìn)程間通信的方式有:信號,信號量,消息隊列,共享內存。
所謂進(jìn)程通信,就是不同進(jìn)程之間進(jìn)行一些"接觸",這種接觸有簡(jiǎn)單,也有復雜。機制不同,復雜度也不一樣。通信是一個(gè)廣義上的意義,不僅僅指傳遞一些massege。
他們的使用方法是基本相同的,所以只要掌握了一種的使用方法,然后記住其他的使用方法就可以了。
1. 信號
在我學(xué)習的內容中,主要接觸了信號來(lái)實(shí)現同步的機制,據說(shuō)信號也可以用來(lái)做其它的事情,但是我還不知道做什么。
信號和信號量是不同的,他們雖然都可用來(lái)實(shí)現同步和互斥,但前者是使用信號處理器來(lái)進(jìn)行的,后者是使用P,V操作來(lái)實(shí)現的。
使用信號要先知道有哪些信號,在Linux下有31個(gè)需要記住的通用信號,據說(shuō)也是systemV中最常用的那些。這里略。
1. 1信號相關(guān)函數:
#include
int sigaction(int signo, const struct sigaction *act, struct sigaction
*oact);
該函數用來(lái)為進(jìn)程安裝信號處理器,struct sigaction數據是用來(lái)保存信號處理器的相關(guān)信息。
#include
int sigemptyset(sigset_t *set);
將信號集合清空。
int sigfillset(sigset_t *set);
將信號集合設置成包含所有的信號。在對信號進(jìn)行操作以前一定要對信號集進(jìn)行初始化。
int sigaddset(sigset_t *set, int signo);
向信號集中加入signo對應的新信號。
int sigdelset(sigset_t *set, int signo);
從信號集中刪除signo對應的一個(gè)信號。
int sigismember(const sigset_t *set, int signo);
判斷某個(gè)信號是否在信號集中。返回1則在,0則不在。
#include
int sigprocmask(int how,const sigset_t *set, sigset_t *oset);用來(lái)設置進(jìn)程的信號屏蔽碼。信號屏蔽碼可以用來(lái)在某段時(shí)間內阻塞一些信號集中的信號,如果信號不在信號集中,就不必討論它,因為肯定不響應,是否能生成也不肯定,我沒(méi)有做過(guò)試驗。
1.2我所理解的使用信號機制的方法:
使用信號,主要做的事情就是信號處理器的工作,這里面是你想做的事情。就像中斷處理函數一樣。
在使用信號以前,首先要初始化信號集,只有在信號集里面的信號才會(huì )被考慮。
有兩種方法可以初始化信號集,一種是設置空信號集,一種是將所有的信號都加到信號集中。如果你自己想要的信號集不是這兩種,可以在初始化了以后通過(guò)添加和刪除信號進(jìn)行定制。
如果在進(jìn)程執行的一段時(shí)間內不想對某些信號進(jìn)行響應,則可以使用sigprocmask對當前的信號集中的一些信號進(jìn)行阻塞,稍后再執行。
用于進(jìn)程間通訊(IPC)的四種不同技術(shù):
1. 消息傳遞(管道,FIFO,posix和system v消息隊列)
2. 同步(互斥鎖,條件變量,讀寫(xiě)鎖,文件和記錄鎖,Posix和System V信號燈)
3. 共享內存區(匿名共享內存區,有名Posix共享內存區,有名System V共享內存區)
4. 過(guò)程調用(Solaris門(mén),Sun RPC)
消息隊列和過(guò)程調用往往單獨使用,也就是說(shuō)它們通常提供了自己的同步機制.相反,共享內存區通常需要由應用程序提供的某種同步形式才能正常工作.解決某個(gè)特定問(wèn)題應使用哪種IPC不存在簡(jiǎn)單的判定,應該逐漸熟悉各種IPC形式提供的機制,然后根據特定應用的要求比較它們的特性.
必須考慮的四個(gè)前提:
1. 聯(lián)網(wǎng)的還是非聯(lián)網(wǎng)的.IPC適用于單臺主機上的進(jìn)程或線(xiàn)程間的.如果應用程序有可能分布到多臺主機上,那就要考慮使用套接字代替IPC,從而簡(jiǎn)化以后向聯(lián)網(wǎng)的應用程序轉移的工作.
2. 可移植性.
3. 性能,在具體的開(kāi)發(fā)環(huán)境下運行測試程序,比較幾種IPC的性能差異.
4. 實(shí)時(shí)調度.如果需要這一特性,而且所用的系統也支持posix實(shí)時(shí)調度選項,那就考慮使用Posix的消息傳遞和同步函數.
各種IPC之間的一些主要差異:
1. 管道和FIFO是字節流,沒(méi)有消息邊界.Posix消息和System V消息則有從發(fā)送者向接受者維護的記錄邊界(eg:TCP是沒(méi)有記錄邊界的字節流,UDP則提供具有記錄邊界的消息).
2. 當有一個(gè)消息放置到一個(gè)空隊列中時(shí),Posix消息隊列可向一個(gè)進(jìn)程發(fā)送一個(gè)信號,或者啟動(dòng)一個(gè)新的線(xiàn)程.System V則不提供類(lèi)似的通知形式.
3. 管道和FIFO的數據字節是先進(jìn)先出的.Posix消息和System V消息具有由發(fā)送者賦予的優(yōu)先級.從一個(gè)Posix消息隊列讀出時(shí),首先返回的總是優(yōu)先級最高的消息.從一個(gè)System V消息隊列讀出時(shí),讀出者可以要求想要的任意優(yōu)先級的消息.
4. 在眾多的消息傳遞技術(shù)—管道,FIFO,Posix消息隊列和System V消息隊列—中,可從一個(gè)信號處理程序中調用的函數只有read和write(適用于管道和FIFO).
比較不同形式的消息傳遞時(shí),我們感興趣的有兩種測量尺度:
1. 帶寬(bandwidth):數據通過(guò)IPC通道轉移的速度.為測量該值,我們從一個(gè)進(jìn)程向另一個(gè)進(jìn)程發(fā)送大量數據(幾百萬(wàn)字節).我們還給不同大小的I/O操作(例如管道和FIFO的write和read操作)測量該值,期待發(fā)現帶寬隨每個(gè)I/O操作的數據量的增長(cháng)而增長(cháng)的規律.
2. 延遲(latency):一個(gè)小的IPC消息從一個(gè)進(jìn)程到令一個(gè)進(jìn)程再返回來(lái)所花的時(shí)間.我們測量的是只有一個(gè)1個(gè)字節的消息從一個(gè)進(jìn)程到令一個(gè)進(jìn)程再回來(lái)的時(shí)間(往返時(shí)間)
在現實(shí)世界中,帶寬告訴我們大塊數據通過(guò)一個(gè)IPC通道發(fā)送出去需花多長(cháng)時(shí)間,然而IPC也用于傳遞小的控制信息,系統處理這些小消息所需的時(shí)間就由延遲提供.這兩個(gè)數都很重要.
什么是系統進(jìn)程
進(jìn)程是指在系統中正在運行的一個(gè)應用程序;線(xiàn)程是系統分配處理器時(shí)間資源的基本單元,或者說(shuō)進(jìn)程之內獨立執行的一個(gè)單元。對于操作系統而言,其調度單元是線(xiàn)程。一個(gè)進(jìn)程至少包括一個(gè)線(xiàn)程,通常將該線(xiàn)程稱(chēng)為主線(xiàn)程。一個(gè)進(jìn)程從主線(xiàn)程的執行開(kāi)始進(jìn)而創(chuàng )建一個(gè)或多個(gè)附加線(xiàn)程,就是所謂基于多線(xiàn)程的多任務(wù)。
那進(jìn)程與線(xiàn)程的區別到底是什么?進(jìn)程是執行程序的實(shí)例。例如,當你運行記事本程序(Nodepad)時(shí),你就創(chuàng )建了一個(gè)用來(lái)容納組成 Notepad.exe的代碼及其所需調用動(dòng)態(tài)鏈接庫的進(jìn)程。每個(gè)進(jìn)程均運行在其專(zhuān)用且受保護的地址空間內。因此,如果你同時(shí)運行記事本的兩個(gè)拷貝,該程序正在使用的數據在各自實(shí)例中是彼此獨立的。在記事本的一個(gè)拷貝中將無(wú)法看到該程序的第二個(gè)實(shí)例打開(kāi)的數據。
以沙箱為例進(jìn)行闡述。一個(gè)進(jìn)程就好比一個(gè)沙箱。線(xiàn)程就如同沙箱中的孩子們。孩子們在沙箱子中跑來(lái)跑去,并且可能將沙子攘到別的孩子眼中,他們會(huì )互相踢打或撕咬。但是,這些沙箱略有不同之處就在于每個(gè)沙箱完全由墻壁和頂棚封閉起來(lái),無(wú)論箱中的孩子如何狠命地攘沙,他們也不會(huì )影響到其它沙箱中的其他孩子。因此,每個(gè)進(jìn)程就象一個(gè)被保護起來(lái)的沙箱。未經(jīng)許可,無(wú)人可以進(jìn)出。
實(shí)際上線(xiàn)程運行而進(jìn)程不運行。兩個(gè)進(jìn)程彼此獲得專(zhuān)用數據或內存的唯一途徑就是通過(guò)協(xié)議來(lái)共享內存塊。這是一種協(xié)作策略。下面讓我們分析一下任務(wù)管理器里的進(jìn)程選項卡。
這里的進(jìn)程是指一系列進(jìn)程,這些進(jìn)程是由它們所運行的可執行程序實(shí)例來(lái)識別的,這就是進(jìn)程選項卡中的第一列給出了映射名稱(chēng)的原因。請注意,這里并沒(méi)有進(jìn)程名稱(chēng)列。進(jìn)程并不擁有獨立于其所歸屬實(shí)例的映射名稱(chēng)。換言之,如果你運行5個(gè)記事本拷貝,你將會(huì )看到5個(gè)稱(chēng)為Notepad.exe的進(jìn)程。它們是如何彼此區別的呢?其中一種方式是通過(guò)它們的進(jìn)程ID,因為每個(gè)進(jìn)程都擁有其獨一無(wú)二的編碼。該進(jìn)程ID由Windows NT或Windows 2000生成,并可以循環(huán)使用。因此,進(jìn)程ID將不會(huì )越編越大,它們能夠得到循環(huán)利用。第三列是被進(jìn)程中的線(xiàn)程所占用的CPU時(shí)間百分比。它不是CPU的編號,而是被進(jìn)程占用的CPU時(shí)間百分比。此時(shí)我的系統基本上是空閑的。盡管系統看上去每一秒左右都只使用一小部分CPU時(shí)間,但該系統空閑進(jìn)程仍舊耗用了大約99%的CPU時(shí)間。
第四列,CPU時(shí)間,是CPU被進(jìn)程中的線(xiàn)程累計占用的小時(shí)、分鐘及秒數。請注意,我對進(jìn)程中的線(xiàn)程使用占用一詞。這并不一定意味著(zhù)那就是進(jìn)程已耗用的CPU時(shí)間總和,因為,如我們一會(huì )兒將看到的,NT計時(shí)的方式是,當特定的時(shí)鐘間隔激發(fā)時(shí),無(wú)論誰(shuí)恰巧處于當前的線(xiàn)程中,它都將計算到CPU周期之內。通常情況下,在大多數NT系統中,時(shí)鐘以10毫秒的間隔運行。每10毫秒NT的心臟就跳動(dòng)一下。有一些驅動(dòng)程序代碼片段運行并顯示誰(shuí)是當前的線(xiàn)程。讓我們將CPU時(shí)間的最后10毫秒記在它的帳上。因此,如果一個(gè)線(xiàn)程開(kāi)始運行,并在持續運行8毫秒后完成,接著(zhù),第二個(gè)線(xiàn)程開(kāi)始運行并持續了2毫秒,這時(shí),時(shí)鐘激發(fā),請猜一猜這整整10毫秒的時(shí)鐘周期到底記在了哪個(gè)線(xiàn)程的帳上?答案是第二個(gè)線(xiàn)程。因此,NT中存在一些固有的不準確性,而NT恰是以這種方式進(jìn)行計時(shí),實(shí)際情況也如是,大多數32位操作系統中都存在一個(gè)基于間隔的計時(shí)機制。請記住這一點(diǎn),因為,有時(shí)當你觀(guān)察線(xiàn)程所耗用的CPU總和時(shí),會(huì )出現盡管該線(xiàn)程或許看上去已運行過(guò)數十萬(wàn)次,但其CPU時(shí)間占用量卻可能是零或非常短暫的現象,那么,上述解釋便是原因所在。上述也就是我們在任務(wù)管理器的進(jìn)程選項卡中所能看到的基本信息列。
1。同步代碼塊:
synchronized(同一個(gè)數據){} 同一個(gè)數據:就是N條線(xiàn)程同時(shí)訪(fǎng)問(wèn)一個(gè)數據。
2。
同步方法:
public synchronized 數據返回類(lèi)型 方法名(){}
就
是使用 synchronized 來(lái)修飾某個(gè)方法,則該方法稱(chēng)為同步方法。對于同步方法而言,無(wú)需顯示指定同步監視器,同步方法的同步監視器是
this
也就是該對象的本身(這里指的對象本身有點(diǎn)含糊,其實(shí)就是調用該同步方法的對象)通過(guò)使用同步方法,可非常方便的將某類(lèi)變成線(xiàn)程安全的類(lèi),具有如下特征:
1,該類(lèi)的對象可以被多個(gè)線(xiàn)程安全的訪(fǎng)問(wèn)。
2,每個(gè)線(xiàn)程調用該對象的任意方法之后,都將得到正確的結果。
3,每個(gè)線(xiàn)程調用該對象的任意方法之后,該對象狀態(tài)依然保持合理狀態(tài)。
注:synchronized關(guān)鍵字可以修飾方法,也可以修飾代碼塊,但不能修飾構造器,屬性等。
實(shí)現同步機制注意以下幾點(diǎn): 安全性高,性能低,在多線(xiàn)程用。性能高,安全性低,在單線(xiàn)程用。
1,不要對線(xiàn)程安全類(lèi)的所有方法都進(jìn)行同步,只對那些會(huì )改變共享資源方法的進(jìn)行同步。
2,如果可變類(lèi)有兩種運行環(huán)境,當線(xiàn)程環(huán)境和多線(xiàn)程環(huán)境則應該為該可變類(lèi)提供兩種版本:線(xiàn)程安全版本和線(xiàn)程不安全版本(沒(méi)有同步方法和同步塊)。在單線(xiàn)程中環(huán)境中,使用線(xiàn)程不安全版本以保證性能,在多線(xiàn)程中使用線(xiàn)程安全版本.
線(xiàn)程通訊:
為什么要使用線(xiàn)程通訊?
當
使用synchronized
來(lái)修飾某個(gè)共享資源時(shí)(分同步代碼塊和同步方法兩種情況),當某個(gè)線(xiàn)程獲得共享資源的鎖后就可以執行相應的代碼段,直到該線(xiàn)程運行完該代碼段后才釋放對該
共享資源的鎖,讓其他線(xiàn)程有機會(huì )執行對該共享資源的修改。當某個(gè)線(xiàn)程占有某個(gè)共享資源的鎖時(shí),如果另外一個(gè)線(xiàn)程也想獲得這把鎖運行就需要使用wait()
和notify()/notifyAll()方法來(lái)進(jìn)行線(xiàn)程通訊了。
Java.lang.object 里的三個(gè)方法wait() notify() notifyAll()
wait方法導致當前線(xiàn)程等待,直到其他線(xiàn)程調用同步監視器的notify方法或notifyAll方法來(lái)喚醒該線(xiàn)程。
wait(mills)方法
都是等待指定時(shí)間后自動(dòng)蘇醒,調用wait方法的當前線(xiàn)程會(huì )釋放該同步監視器的鎖定,可以不用notify或notifyAll方法把它喚醒。
notify()
喚醒在同步監視器上等待的單個(gè)線(xiàn)程,如果所有線(xiàn)程都在同步監視器上等待,則會(huì )選擇喚醒其中一個(gè)線(xiàn)程,選擇是任意性的,只有當前線(xiàn)程放棄對該同步監視器的鎖定后,也就是使用wait方法后,才可以執行被喚醒的線(xiàn)程。
notifyAll()方法
喚醒在同步監視器上等待的所有的線(xiàn)程。只用當前線(xiàn)程放棄對該同步監視器的鎖定后,才可以執行被喚醒的線(xiàn)程
lz你好,
在操作系統中,有很多術(shù)語(yǔ)都是想通的,都是相似的,相近的。比如同步、異步、并行、并發(fā)、互斥等等。對這類(lèi)詞語(yǔ),如果沒(méi)有同時(shí)出現,我們對它們最好的處理就是不去比較它們,因為很多都沒(méi)有可比性。
首先:互斥和同步如果是同時(shí)出現的話(huà),那就是相反的,值得比較的兩個(gè)術(shù)語(yǔ)。
【互斥】:就是說(shuō)兩個(gè)進(jìn)程只能在某一時(shí)刻執行一個(gè),這種結果可能是因為共同爭奪資源而產(chǎn)生的。舉個(gè)例子:假設把火車(chē)上的公共廁所看成一種臨界資源,而兩個(gè)乘客是兩個(gè)進(jìn)程,我們就可以認為同時(shí)需要使用公共廁所的乘客是互斥的
【同步】:就是進(jìn)程之間可以同時(shí)運行的,之間并不存在“利益沖突”,不競爭資源。大有“你走你的陽(yáng)關(guān)道,我過(guò)我的獨木橋”之意,兩個(gè)進(jìn)程互不干涉,互不影響。
說(shuō)的很直白了,希望可以幫你o(∩_∩)o
聲明:本網(wǎng)站尊重并保護知識產(chǎn)權,根據《信息網(wǎng)絡(luò )傳播權保護條例》,如果我們轉載的作品侵犯了您的權利,請在一個(gè)月內通知我們,我們會(huì )及時(shí)刪除。
蜀ICP備2020033479號-4 Copyright ? 2016 學(xué)習?shū)B(niǎo). 頁(yè)面生成時(shí)間:2.956秒