![UNIX進(jìn)程通信_(tái)第1頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2022-2/22/d91e078a-9336-4941-ac87-da483e66f405/d91e078a-9336-4941-ac87-da483e66f4051.gif)
![UNIX進(jìn)程通信_(tái)第2頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2022-2/22/d91e078a-9336-4941-ac87-da483e66f405/d91e078a-9336-4941-ac87-da483e66f4052.gif)
![UNIX進(jìn)程通信_(tái)第3頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2022-2/22/d91e078a-9336-4941-ac87-da483e66f405/d91e078a-9336-4941-ac87-da483e66f4053.gif)
![UNIX進(jìn)程通信_(tái)第4頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2022-2/22/d91e078a-9336-4941-ac87-da483e66f405/d91e078a-9336-4941-ac87-da483e66f4054.gif)
![UNIX進(jìn)程通信_(tái)第5頁(yè)](http://file3.renrendoc.com/fileroot_temp3/2022-2/22/d91e078a-9336-4941-ac87-da483e66f405/d91e078a-9336-4941-ac87-da483e66f4055.gif)
版權(quán)說(shuō)明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡(jiǎn)介
1、進(jìn)程通信:多個(gè)進(jìn)程并發(fā)執(zhí)行如何協(xié)調(diào)它們之間的功能進(jìn)程通信:多個(gè)進(jìn)程并發(fā)執(zhí)行如何協(xié)調(diào)它們之間的功能 1 通信分為兩類通信分為兩類 控制信息的傳遞:控制信息的傳遞: 低級(jí)通信低級(jí)通信 大批量數(shù)據(jù)的傳遞:大批量數(shù)據(jù)的傳遞: 高級(jí)通信高級(jí)通信 2基本的通信方式基本的通信方式 (a)主從式通信:)主從式通信: 通信的雙方存在一種隸屬關(guān)系通信的雙方存在一種隸屬關(guān)系 (b)會(huì)話式通信:)會(huì)話式通信: 通信進(jìn)程雙方采用請(qǐng)求應(yīng)答的方式進(jìn)行通信通信進(jìn)程雙方采用請(qǐng)求應(yīng)答的方式進(jìn)行通信 使用者進(jìn)程 服務(wù)者進(jìn)程 request response 2基本的通信方式基本的通信方式 (c)消息或郵件通信:)消息或郵件通信:
2、通信雙方處于一個(gè)平等地位,發(fā)的消息通通信雙方處于一個(gè)平等地位,發(fā)的消息通過(guò)消息系統(tǒng)或郵件系統(tǒng)進(jìn)行大批量數(shù)據(jù)傳遞。過(guò)消息系統(tǒng)或郵件系統(tǒng)進(jìn)行大批量數(shù)據(jù)傳遞。 消息緩沖或郵箱 發(fā)送進(jìn)程 接收進(jìn)程 2基本的通信方式基本的通信方式 (d)共享存儲(chǔ)區(qū)通信:進(jìn)程之間采用進(jìn)程通信信息共享存儲(chǔ)區(qū)的共享存儲(chǔ)區(qū)通信:進(jìn)程之間采用進(jìn)程通信信息共享存儲(chǔ)區(qū)的通信方式來(lái)完成進(jìn)程間的通信。通信方式來(lái)完成進(jìn)程間的通信。 共享存儲(chǔ)區(qū)共享存儲(chǔ)區(qū)進(jìn)程進(jìn)程1進(jìn)程進(jìn)程2 基本通信:早期的基本通信:早期的UNIX系統(tǒng)采用,簡(jiǎn)單的信息傳遞,協(xié)調(diào)進(jìn)程之間的系統(tǒng)采用,簡(jiǎn)單的信息傳遞,協(xié)調(diào)進(jìn)程之間的同步和互斥。同步和互斥。 管道通信:大批量的數(shù)據(jù)
3、傳送,有名管道和無(wú)名管道。管道通信:大批量的數(shù)據(jù)傳送,有名管道和無(wú)名管道。 IPC :采用消息方式進(jìn)行進(jìn)程間通信。:采用消息方式進(jìn)行進(jìn)程間通信。 1基本通信基本通信(1) 鎖文件通信:鎖文件通信: 通信雙方在某個(gè)指定目錄中查找是否有個(gè)雙方約定的文件存在,并以此來(lái)決定通信雙方在某個(gè)指定目錄中查找是否有個(gè)雙方約定的文件存在,并以此來(lái)決定通信的動(dòng)作以及對(duì)應(yīng)的邏輯。進(jìn)程用對(duì)通信的動(dòng)作以及對(duì)應(yīng)的邏輯。進(jìn)程用對(duì)“鎖文件創(chuàng)建與否鎖文件創(chuàng)建與否”狀態(tài)的判定和設(shè)置狀態(tài)的判定和設(shè)置完成一個(gè)進(jìn)程到另一個(gè)進(jìn)程之間的通信。完成一個(gè)進(jìn)程到另一個(gè)進(jìn)程之間的通信。(2) 記錄鎖定文件通信記錄鎖定文件通信 即是通過(guò)對(duì)記錄(文件
4、中連續(xù)的字節(jié)組成特定的數(shù)據(jù))的鎖定來(lái)實(shí)現(xiàn)進(jìn)程通信。即是通過(guò)對(duì)記錄(文件中連續(xù)的字節(jié)組成特定的數(shù)據(jù))的鎖定來(lái)實(shí)現(xiàn)進(jìn)程通信。(3)信號(hào)信號(hào) 使用軟中斷信號(hào)的通信方式。信號(hào)可以做預(yù)先的說(shuō)明,用戶使用時(shí)只需要根使用軟中斷信號(hào)的通信方式。信號(hào)可以做預(yù)先的說(shuō)明,用戶使用時(shí)只需要根據(jù)信號(hào)的約定來(lái)完成進(jìn)程之間的通信。據(jù)信號(hào)的約定來(lái)完成進(jìn)程之間的通信。 基本概念基本概念 信號(hào)是信號(hào)是UNIX操作系統(tǒng)用來(lái)通知進(jìn)程發(fā)生了某種事件的一種手段操作系統(tǒng)用來(lái)通知進(jìn)程發(fā)生了某種事件的一種手段 信號(hào)也稱為軟中斷,它提供了一種處理異步事件的方法信號(hào)也稱為軟中斷,它提供了一種處理異步事件的方法 信號(hào)也可以用于進(jìn)程之間進(jìn)行通信和實(shí)現(xiàn)
5、進(jìn)程同步處理信號(hào)也可以用于進(jìn)程之間進(jìn)行通信和實(shí)現(xiàn)進(jìn)程同步處理信號(hào)的定義:信號(hào)的定義: 信號(hào)是傳送給進(jìn)程的一種信號(hào)是傳送給進(jìn)程的一種事件事件通知,通知,UNIX系統(tǒng)為每一種可能的系統(tǒng)為每一種可能的事件定義了一組信號(hào),每一個(gè)信號(hào)有一個(gè)信號(hào)名,名字均以事件定義了一組信號(hào),每一個(gè)信號(hào)有一個(gè)信號(hào)名,名字均以SIG打頭打頭很多種情況會(huì)產(chǎn)生信號(hào)很多種情況會(huì)產(chǎn)生信號(hào)當(dāng)用戶在終端按下某些鍵時(shí),產(chǎn)生終端生成的信號(hào),例如:當(dāng)用戶在終端按下某些鍵時(shí),產(chǎn)生終端生成的信號(hào),例如:按下按下Delete鍵或者鍵或者Ctrl-c通常產(chǎn)生一個(gè)中斷信號(hào)通常產(chǎn)生一個(gè)中斷信號(hào) SIGINT,這是停止正在,這是停止正在運(yùn)行的程序的一種常
6、用手段運(yùn)行的程序的一種常用手段硬件例外會(huì)產(chǎn)生信號(hào),例如:硬件例外會(huì)產(chǎn)生信號(hào),例如:零作為除數(shù)、非法存儲(chǔ)器訪問(wèn)等。這種情況通常是由硬件而不是零作為除數(shù)、非法存儲(chǔ)器訪問(wèn)等。這種情況通常是由硬件而不是UNIX內(nèi)核內(nèi)核檢測(cè)到的,但由內(nèi)核向發(fā)生此錯(cuò)誤的哪個(gè)進(jìn)程發(fā)送相應(yīng)的信號(hào),比如發(fā)生非檢測(cè)到的,但由內(nèi)核向發(fā)生此錯(cuò)誤的哪個(gè)進(jìn)程發(fā)送相應(yīng)的信號(hào),比如發(fā)生非法存儲(chǔ)器訪問(wèn)時(shí),信號(hào)法存儲(chǔ)器訪問(wèn)時(shí),信號(hào)SIGSEGV將被內(nèi)核發(fā)送到執(zhí)行了該非法訪問(wèn)的進(jìn)程。將被內(nèi)核發(fā)送到執(zhí)行了該非法訪問(wèn)的進(jìn)程。如果發(fā)生了某種必須讓進(jìn)程知道的情況時(shí)也會(huì)生成信號(hào)。這里的情況不是硬如果發(fā)生了某種必須讓進(jìn)程知道的情況時(shí)也會(huì)生成信號(hào)。這里的情況不
7、是硬件產(chǎn)生的,而是軟條件,例如:件產(chǎn)生的,而是軟條件,例如:當(dāng)進(jìn)程設(shè)置的定時(shí)器到期時(shí)將生成當(dāng)進(jìn)程設(shè)置的定時(shí)器到期時(shí)將生成SIGALRM信號(hào)信號(hào)當(dāng)進(jìn)程向一個(gè)管道寫數(shù)據(jù),而此管道已不存在讀數(shù)據(jù)方時(shí),生成當(dāng)進(jìn)程向一個(gè)管道寫數(shù)據(jù),而此管道已不存在讀數(shù)據(jù)方時(shí),生成SIGPIPE信號(hào)信號(hào)某些系統(tǒng)調(diào)用將產(chǎn)生信號(hào),例如某些系統(tǒng)調(diào)用將產(chǎn)生信號(hào),例如kill函數(shù)將允許進(jìn)程發(fā)送任何信號(hào)給本進(jìn)程,其他的進(jìn)程或者進(jìn)程組函數(shù)將允許進(jìn)程發(fā)送任何信號(hào)給本進(jìn)程,其他的進(jìn)程或者進(jìn)程組raise函數(shù)能夠發(fā)送任何一個(gè)信號(hào)給調(diào)用它的進(jìn)程函數(shù)能夠發(fā)送任何一個(gè)信號(hào)給調(diào)用它的進(jìn)程生成信號(hào)的事件可以歸并為三大類生成信號(hào)的事件可以歸并為三大類1
8、.程序錯(cuò)誤程序錯(cuò)誤 例如零作除數(shù)、非法存儲(chǔ)器訪問(wèn)等例如零作除數(shù)、非法存儲(chǔ)器訪問(wèn)等2. 外部事件外部事件 例如用戶按下例如用戶按下Delete鍵、定時(shí)器到期等鍵、定時(shí)器到期等3. 顯式請(qǐng)求顯式請(qǐng)求 進(jìn)程主動(dòng)調(diào)用進(jìn)程主動(dòng)調(diào)用kill函數(shù)或者函數(shù)或者raise函數(shù)函數(shù)同步信號(hào)和異步信號(hào)同步信號(hào)和異步信號(hào)信號(hào)的生成可以是同步的,也可以是異步的。信號(hào)的生成可以是同步的,也可以是異步的。 同步信號(hào)與程序中的某個(gè)具體操作相關(guān)并且在那個(gè)操作進(jìn)行時(shí)同時(shí)產(chǎn)生。同步信號(hào)與程序中的某個(gè)具體操作相關(guān)并且在那個(gè)操作進(jìn)行時(shí)同時(shí)產(chǎn)生。 多數(shù)程序錯(cuò)誤生成的信號(hào)是同步的,例如除零錯(cuò)或內(nèi)存訪問(wèn)錯(cuò)多數(shù)程序錯(cuò)誤生成的信號(hào)是同步的,例如
9、除零錯(cuò)或內(nèi)存訪問(wèn)錯(cuò) 由進(jìn)程顯示請(qǐng)求而生成的給自己的信號(hào)也是同步的,例如由進(jìn)程顯示請(qǐng)求而生成的給自己的信號(hào)也是同步的,例如raise系統(tǒng)調(diào)用系統(tǒng)調(diào)用 異步信號(hào)是接收該信號(hào)的進(jìn)程控制之外的事件生成的信號(hào)異步信號(hào)是接收該信號(hào)的進(jìn)程控制之外的事件生成的信號(hào) 一般外部事件總是異步的生成信號(hào)一般外部事件總是異步的生成信號(hào) 作用于其他進(jìn)程的作用于其他進(jìn)程的kill系統(tǒng)調(diào)用也異步地生成信號(hào)系統(tǒng)調(diào)用也異步地生成信號(hào) 異步信號(hào)可以在進(jìn)程運(yùn)行任意時(shí)刻產(chǎn)生,進(jìn)程無(wú)法預(yù)期信號(hào)到達(dá)的時(shí)刻異步信號(hào)可以在進(jìn)程運(yùn)行任意時(shí)刻產(chǎn)生,進(jìn)程無(wú)法預(yù)期信號(hào)到達(dá)的時(shí)刻對(duì)信號(hào)的處理對(duì)信號(hào)的處理無(wú)論是同步還是異步信號(hào),信號(hào)發(fā)生時(shí),系統(tǒng)對(duì)信號(hào)可以
10、采用無(wú)論是同步還是異步信號(hào),信號(hào)發(fā)生時(shí),系統(tǒng)對(duì)信號(hào)可以采用3種處理方式種處理方式忽略信號(hào)忽略信號(hào) 大部分信號(hào)都可以被忽略,只有大部分信號(hào)都可以被忽略,只有2個(gè)除外個(gè)除外SIGSTOP和和SIGKILL。這兩個(gè)信號(hào)是為了給。這兩個(gè)信號(hào)是為了給root用戶提供殺掉或停止任何進(jìn)用戶提供殺掉或停止任何進(jìn)程的一種手段。程的一種手段。調(diào)用默認(rèn)動(dòng)作調(diào)用默認(rèn)動(dòng)作 系統(tǒng)為每種信號(hào)規(guī)定了一個(gè)默認(rèn)動(dòng)作,如果用戶進(jìn)系統(tǒng)為每種信號(hào)規(guī)定了一個(gè)默認(rèn)動(dòng)作,如果用戶進(jìn)程沒(méi)有為某個(gè)信號(hào)設(shè)置句柄,則該信號(hào)到達(dá)時(shí),對(duì)該信號(hào)的處理程沒(méi)有為某個(gè)信號(hào)設(shè)置句柄,則該信號(hào)到達(dá)時(shí),對(duì)該信號(hào)的處理由由UNIX內(nèi)核來(lái)完成。通常的默認(rèn)動(dòng)作有內(nèi)核來(lái)完成
11、。通常的默認(rèn)動(dòng)作有: core dump, 終止進(jìn)程,終止進(jìn)程,忽略信號(hào),進(jìn)程掛起等幾種。忽略信號(hào),進(jìn)程掛起等幾種。捕獲信號(hào)捕獲信號(hào) 需要告訴需要告訴UNIX系統(tǒng)內(nèi)核,當(dāng)該信號(hào)出現(xiàn)時(shí),調(diào)用專門系統(tǒng)內(nèi)核,當(dāng)該信號(hào)出現(xiàn)時(shí),調(diào)用專門提供的一個(gè)函數(shù),類似于提供的一個(gè)函數(shù),類似于MFC中的事件函數(shù)的概念。這個(gè)函數(shù)稱中的事件函數(shù)的概念。這個(gè)函數(shù)稱為信號(hào)句柄,或者簡(jiǎn)稱為句柄,它專門對(duì)產(chǎn)生信號(hào)的事件作出處為信號(hào)句柄,或者簡(jiǎn)稱為句柄,它專門對(duì)產(chǎn)生信號(hào)的事件作出處理。系統(tǒng)調(diào)用理。系統(tǒng)調(diào)用sigal為特定信號(hào)設(shè)置信號(hào)句柄為特定信號(hào)設(shè)置信號(hào)句柄UNIX系統(tǒng)中常用的信號(hào)系統(tǒng)中常用的信號(hào)信號(hào)信號(hào)描述描述默認(rèn)處理默認(rèn)處理S
12、IGABRT進(jìn)程異常中止,調(diào)用進(jìn)程異常中止,調(diào)用abort函數(shù)生成該信號(hào)函數(shù)生成該信號(hào)異常中止異常中止SIGALRM實(shí)時(shí)鬧鐘實(shí)時(shí)鬧鐘進(jìn)程退出進(jìn)程退出SIGFPE算術(shù)例外算術(shù)例外異常中止異常中止SIGHUP掛起進(jìn)程掛起進(jìn)程進(jìn)程退出進(jìn)程退出SIGILL非法硬件指令非法硬件指令異常終止異常終止SIGKILL終止進(jìn)程終止進(jìn)程進(jìn)程退出進(jìn)程退出SIGPIPE寫沒(méi)有讀者的管道寫沒(méi)有讀者的管道進(jìn)程退出進(jìn)程退出UNIX系統(tǒng)中常用的信號(hào)系統(tǒng)中常用的信號(hào)信號(hào)信號(hào)描述描述默認(rèn)處理默認(rèn)處理SIGQUIT終端終端quit字符字符 (ctrl-)異常終止異常終止SIGSEGV非法存儲(chǔ)訪問(wèn)(地址越界)非法存儲(chǔ)訪問(wèn)(地址越界)
13、異常終止異常終止SIGTERM終止進(jìn)程終止進(jìn)程退出退出SIGTRAP硬件自陷硬件自陷異常終止異常終止SIGUSR1用戶自定義信號(hào)用戶自定義信號(hào)退出退出SIGUSR2用戶自定義信號(hào)用戶自定義信號(hào)退出退出SIGSTOP停止進(jìn)程停止進(jìn)程退出退出指定和改變信號(hào)的動(dòng)作指定和改變信號(hào)的動(dòng)作 對(duì)于每一種信號(hào),進(jìn)程可以指定要么忽略它,要么采取默認(rèn)動(dòng)作,對(duì)于每一種信號(hào),進(jìn)程可以指定要么忽略它,要么采取默認(rèn)動(dòng)作,或者為它指定一個(gè)自定義的捕獲函數(shù);進(jìn)程也可以在任何時(shí)候?qū)σ粋€(gè)或者為它指定一個(gè)自定義的捕獲函數(shù);進(jìn)程也可以在任何時(shí)候?qū)σ粋€(gè)信號(hào)重新指定其動(dòng)作或者回到其原先的動(dòng)作。信號(hào)重新指定其動(dòng)作或者回到其原先的動(dòng)作。系統(tǒng)
14、調(diào)用系統(tǒng)調(diào)用 signal函數(shù)函數(shù)void* signal(int sig, void(* func)(int) ) ;參數(shù)參數(shù)sig是個(gè)整數(shù),指明該系統(tǒng)調(diào)用處理哪一個(gè)信號(hào)是個(gè)整數(shù),指明該系統(tǒng)調(diào)用處理哪一個(gè)信號(hào)參數(shù)參數(shù)func指明信號(hào)指明信號(hào)sig發(fā)生時(shí),系統(tǒng)可以采取的發(fā)生時(shí),系統(tǒng)可以采取的3種動(dòng)作之一:種動(dòng)作之一:常數(shù)常數(shù) SIG_DFL 指明對(duì)信號(hào)采用默認(rèn)動(dòng)作指明對(duì)信號(hào)采用默認(rèn)動(dòng)作常數(shù)常數(shù) SIG_IGN 指明該信號(hào)發(fā)生時(shí),系統(tǒng)將忽略它指明該信號(hào)發(fā)生時(shí),系統(tǒng)將忽略它信號(hào)句柄地址信號(hào)句柄地址 用戶自定義的信號(hào)處理函數(shù),信號(hào)發(fā)生時(shí),系統(tǒng)將調(diào)用該函數(shù)用戶自定義的信號(hào)處理函數(shù),信號(hào)發(fā)生時(shí),系統(tǒng)將調(diào)
15、用該函數(shù)進(jìn)行處理進(jìn)行處理void* signal(int sig, void(* func)(int) )函數(shù)的注意事項(xiàng)函數(shù)的注意事項(xiàng) 由由signal函數(shù)建立的信號(hào)句柄應(yīng)當(dāng)是一個(gè)僅有一個(gè)整形參數(shù)且函數(shù)建立的信號(hào)句柄應(yīng)當(dāng)是一個(gè)僅有一個(gè)整形參數(shù)且沒(méi)有返回值的函數(shù),其整形參數(shù)指明該生成的信號(hào)沒(méi)有返回值的函數(shù),其整形參數(shù)指明該生成的信號(hào) signal函數(shù)的返回值是指向信號(hào)函數(shù)的返回值是指向信號(hào)sig的前一次有效動(dòng)作的指針,的前一次有效動(dòng)作的指針,當(dāng)該函數(shù)調(diào)用成功,將返回當(dāng)該函數(shù)調(diào)用成功,將返回SIG_DFL、SIG_IGN,或者信號(hào)句柄,或者信號(hào)句柄地址地址 當(dāng)信號(hào)發(fā)生時(shí),如果當(dāng)信號(hào)發(fā)生時(shí),如果fu
16、nc指向信號(hào)句柄,系統(tǒng)在把控制轉(zhuǎn)到信指向信號(hào)句柄,系統(tǒng)在把控制轉(zhuǎn)到信號(hào)句柄之前,將首先改變?cè)撔盘?hào)的動(dòng)作為號(hào)句柄之前,將首先改變?cè)撔盘?hào)的動(dòng)作為SIG_DFL 如果如果signal調(diào)用出錯(cuò),它返回調(diào)用出錯(cuò),它返回SIG_ERR,唯一的錯(cuò)誤碼是,唯一的錯(cuò)誤碼是EINVAL,即是,即是sig給出的信號(hào)數(shù)非法給出的信號(hào)數(shù)非法實(shí)例:實(shí)例:sig.c#include void signal_handle(int the_signal); /定義一個(gè)信號(hào)句柄函數(shù)的原型定義一個(gè)信號(hào)句柄函數(shù)的原型void main( void ) printf(“the process id is %dn”, getpid();
17、 if ( signal(SIGUSR1, signal_handle ) = SIG_ERR ) err_exit(“can not catch SIGUSR1n”); if ( signal(SIGUSR2, signal_handle ) = SIG_ERR ) err_exit(“can not catch SIGUSR2n”); for( ; ; ) pause(); void signal_handle(int the_signal) if ( the_signal = SIGUSR1 ) printf(“the sigal is SIGUSR1”); else if ( the_
18、signal = SIGUSR2) printf(“the sigal is SIGUSR2”); else printf(“the received signal is %dn”, the_signal);%a.out&the process id is 7346%執(zhí)行上面源代碼編譯后的程執(zhí)行上面源代碼編譯后的程序,并調(diào)度到后臺(tái)運(yùn)行序,并調(diào)度到后臺(tái)運(yùn)行kill -USR1 7346發(fā)送信號(hào)發(fā)送信號(hào)SIGUSR1給進(jìn)程號(hào)給進(jìn)程號(hào)為為7346的進(jìn)程的進(jìn)程the sigal is SIGUSR1 %后臺(tái)進(jìn)程后臺(tái)進(jìn)程7346收到收到SIGUSR1信信號(hào)并調(diào)用信號(hào)句柄號(hào)并調(diào)用信號(hào)句柄kill
19、-USR2 7346發(fā)送信號(hào)發(fā)送信號(hào)SIGUSR2給進(jìn)程號(hào)給進(jìn)程號(hào)為為7346的進(jìn)程的進(jìn)程the sigal is SIGUSR2 %后臺(tái)進(jìn)程后臺(tái)進(jìn)程7346收到收到SIGUSR2信信號(hào)并調(diào)用信號(hào)句柄號(hào)并調(diào)用信號(hào)句柄kill 7346發(fā)送信號(hào)發(fā)送信號(hào)SIGTERM給進(jìn)程號(hào)為給進(jìn)程號(hào)為7346的進(jìn)程的進(jìn)程,表示要結(jié)束該進(jìn)程表示要結(jié)束該進(jìn)程1+Terminated a.out&%后臺(tái)進(jìn)程后臺(tái)進(jìn)程7346收到收到SIGTERM信號(hào)信號(hào),調(diào)用調(diào)用默認(rèn)信號(hào)動(dòng)作,該動(dòng)作終止進(jìn)程默認(rèn)信號(hào)動(dòng)作,該動(dòng)作終止進(jìn)程信號(hào)的生成信號(hào)的生成信號(hào)的產(chǎn)生,可以使用三個(gè)系統(tǒng)調(diào)用信號(hào)的產(chǎn)生,可以使用三個(gè)系統(tǒng)調(diào)用int r
20、aise( int sig );int kill( pid_t pid, int sig ); unisigned int alarm( unsigned int seconds ); raiseraise函數(shù)的實(shí)例函數(shù)的實(shí)例#include void sig_tstp_handle( int sig ) signal(SIGTSTP, SIG_DFL); /*做清理動(dòng)作做清理動(dòng)作,SIGTSTP是一個(gè)交互停止信號(hào),類似于停止信號(hào)是一個(gè)交互停止信號(hào),類似于停止信號(hào)SIGSTOP*/ . . . . . raise(SIGTSTP);void main() signal(SIGTSTP, sig
21、_tstp_handle); . . . . . . . /事務(wù)處理代碼事務(wù)處理代碼 killkill函數(shù)的實(shí)例函數(shù)的實(shí)例#include void catch_sig_int( ing signo ) printf(“SIGINT was caught,user pressed keydeleten”); void main() int i = 0; signal( SIGINT, catch_sig_int ); for( i=0; i5; i+ ) printf(“ Sleep called #%dn”, i ); sleep(1); printf(“exiting.n”); alarm
22、(unsigned int seconds); alarm函數(shù)和時(shí)間有點(diǎn)關(guān)系函數(shù)和時(shí)間有點(diǎn)關(guān)系,這個(gè)函數(shù)可以在這個(gè)函數(shù)可以在seconds秒后向自己發(fā)送一個(gè)秒后向自己發(fā)送一個(gè)SIGALRM信號(hào)信號(hào). main() unsigned int i; alarm(1); for(i=0; ; i+) printf(I=%d,i); 信號(hào)操作:有時(shí)候我們希望進(jìn)程正確的執(zhí)行信號(hào)操作:有時(shí)候我們希望進(jìn)程正確的執(zhí)行,而不想進(jìn)程受到信號(hào)的而不想進(jìn)程受到信號(hào)的影響影響,比如我們希望上面那個(gè)程序在比如我們希望上面那個(gè)程序在1秒鐘之后不結(jié)束秒鐘之后不結(jié)束.這個(gè)時(shí)候我們就這個(gè)時(shí)候我們就要進(jìn)行信號(hào)的操作要進(jìn)行信號(hào)的操作
23、. 信號(hào)操作最常用的方法是信號(hào)屏蔽,即是進(jìn)程屏蔽掉某些指定的信號(hào)操作最常用的方法是信號(hào)屏蔽,即是進(jìn)程屏蔽掉某些指定的信號(hào)信號(hào). 信號(hào)屏蔽要用到信號(hào)屏蔽要用到信號(hào)集信號(hào)集的概念和幾個(gè)重要的函數(shù)的概念和幾個(gè)重要的函數(shù). 信號(hào)集信號(hào)集 該數(shù)據(jù)結(jié)構(gòu)可以表示系統(tǒng)支持的每一個(gè)信號(hào)該數(shù)據(jù)結(jié)構(gòu)可以表示系統(tǒng)支持的每一個(gè)信號(hào). 在在 signal.h中定義了中定義了 sigset_t 來(lái)描述信號(hào)集來(lái)描述信號(hào)集主要的信號(hào)操作函數(shù)主要的信號(hào)操作函數(shù) int sigemptyset(sigset_t *set); int sigfillset(sigset_t *set); int sigaddset(sigset_t
24、 *set,int signo); int sigdelset(sigset_t *set,int signo); int sigismember(sigset_t *set,int signo); int sigprocmask(int how,const sigset_t *set,sigset_t *oset); !注意:信號(hào)操作函數(shù)注意:信號(hào)操作函數(shù) 不能對(duì)信號(hào)不能對(duì)信號(hào)SIGKILL和和SIGSTOP進(jìn)行阻塞屏蔽進(jìn)行阻塞屏蔽以一個(gè)實(shí)例來(lái)解釋使用這幾個(gè)函數(shù)以一個(gè)實(shí)例來(lái)解釋使用這幾個(gè)函數(shù). int main() sigset_t intmask; sigemptyset( &in
25、tmask ); / 將信號(hào)集合初始化為空將信號(hào)集合初始化為空 sigaddset( &intmask, SIGINT ); / 加入中斷加入中斷 Ctrl+C 信號(hào)信號(hào) sigaddset( &intmask, SIGTSTP ); / 加入加入 SIGTSTP信號(hào)信號(hào) sigaddset( &intmask, SIGALRM ); / 加入加入 SIGTSTP信號(hào)信號(hào) sigaddset( &intmask, SIGTERM ); / 加入加入 SIGTERM信號(hào)信號(hào) sigprocmask(SIG_BLOCK,&intmask,NULL); /阻塞
26、信號(hào)集阻塞信號(hào)集intmask中的所有信號(hào)中的所有信號(hào),不保存原來(lái)信號(hào)集所以不保存原來(lái)信號(hào)集所以oset為為NULL /* 進(jìn)行事務(wù)操作,期間進(jìn)程不會(huì)被用戶中斷,保證事務(wù)處理的完成進(jìn)行事務(wù)操作,期間進(jìn)程不會(huì)被用戶中斷,保證事務(wù)處理的完成 */ sigprocmask(SIG_UNBLOCK,&intmask,NULL); /放開(kāi)上面阻塞的信號(hào)集放開(kāi)上面阻塞的信號(hào)集 return;等待信號(hào):如果程序是由外部事件所驅(qū)動(dòng)的,或者使用信號(hào)進(jìn)行同步,等待信號(hào):如果程序是由外部事件所驅(qū)動(dòng)的,或者使用信號(hào)進(jìn)行同步,則需要等待信號(hào)的到達(dá)則需要等待信號(hào)的到達(dá). UNIXUNIX系統(tǒng)提供函數(shù)系統(tǒng)提供函數(shù)p
27、ause() pause() 和和 sigsuspendsigsuspend()()來(lái)等待信號(hào)來(lái)等待信號(hào)intint pause(void); pause(void);int sigsuspend( sigset_t int sigsuspend( sigset_t * *sigmasksigmask););以一個(gè)實(shí)例來(lái)解釋使用這個(gè)函數(shù)以一個(gè)實(shí)例來(lái)解釋使用這個(gè)函數(shù). int main() . . . . . . / 功能代碼功能代碼 sigset_t mask; sigset_t old_mask sigemptyset(&mask); / 將信號(hào)集合初始化為空將信號(hào)集合初始化為空 s
28、igaddset(&intmask, SIGUSR1); / 加入加入 SIGUSR1 信號(hào)信號(hào) sigprocmask(SIG_BLOCK,&mask, &old_mask); /獲取系統(tǒng)當(dāng)前信號(hào)屏蔽獲取系統(tǒng)當(dāng)前信號(hào)屏蔽 sigsuspend( &old_mask);/等待信號(hào)的到達(dá),且是當(dāng)前信號(hào)屏蔽集外的信等待信號(hào)的到達(dá),且是當(dāng)前信號(hào)屏蔽集外的信號(hào)號(hào) sigprocmask(SIG_SETMASK ,&old_mask, NULL ); /恢復(fù)系統(tǒng)原來(lái)的信號(hào)屏蔽恢復(fù)系統(tǒng)原來(lái)的信號(hào)屏蔽 . . . . . . . . return;u 管道(管道(pi
29、pe)是)是UNIX中最古老的進(jìn)程間通信工具,它提供進(jìn)中最古老的進(jìn)程間通信工具,它提供進(jìn)程之間單向通信的方法。簡(jiǎn)單說(shuō),管道是連接一個(gè)進(jìn)程的輸出到程之間單向通信的方法。簡(jiǎn)單說(shuō),管道是連接一個(gè)進(jìn)程的輸出到另一個(gè)進(jìn)程的輸入的一種方法另一個(gè)進(jìn)程的輸入的一種方法簡(jiǎn)介簡(jiǎn)介u 管道(管道(pipe)的使用很廣泛,最常見(jiàn)是在命令行中)的使用很廣泛,最常見(jiàn)是在命令行中%cat file | grep pipe | morefilecatgrepmore終端終端管道管道u UNIX中的管道用于進(jìn)程通信,是一種先進(jìn)先出(中的管道用于進(jìn)程通信,是一種先進(jìn)先出(FIFO)的特)的特殊文件,通常是一個(gè)進(jìn)程向管道中寫入數(shù)據(jù)
30、,另一個(gè)進(jìn)程從管殊文件,通常是一個(gè)進(jìn)程向管道中寫入數(shù)據(jù),另一個(gè)進(jìn)程從管道中讀出數(shù)據(jù),從而完成通信的目的。道中讀出數(shù)據(jù),從而完成通信的目的。實(shí)現(xiàn)原理實(shí)現(xiàn)原理管道的特點(diǎn)管道的特點(diǎn)u 管道單獨(dú)構(gòu)成一種特殊的文件管道單獨(dú)構(gòu)成一種特殊的文件。u 管道中,寫入的內(nèi)容每次都添加在管道的末尾,并且每次都是管道中,寫入的內(nèi)容每次都添加在管道的末尾,并且每次都是從管道的頭部讀出數(shù)據(jù),就像隊(duì)列從管道的頭部讀出數(shù)據(jù),就像隊(duì)列不同點(diǎn)是:不同點(diǎn)是:u對(duì)管道寫入時(shí),每次對(duì)管道寫入時(shí),每次write調(diào)用的結(jié)果總是附加在管道的末端,而調(diào)用的結(jié)果總是附加在管道的末端,而文件的寫入不遵守這個(gè)規(guī)定,它可以通過(guò)指針隨意移動(dòng)文件的寫入不
31、遵守這個(gè)規(guī)定,它可以通過(guò)指針隨意移動(dòng)u對(duì)管道寫入時(shí),每次寫入的字節(jié)數(shù)不能超過(guò)系統(tǒng)常量對(duì)管道寫入時(shí),每次寫入的字節(jié)數(shù)不能超過(guò)系統(tǒng)常量PIPE_BUF,而對(duì)文件寫入則沒(méi)有這種規(guī)則而對(duì)文件寫入則沒(méi)有這種規(guī)則(a)管道寫和一般文件寫)管道寫和一般文件寫(write)相同點(diǎn)是:相同點(diǎn)是:u 當(dāng)設(shè)備處于忙狀態(tài)時(shí),當(dāng)設(shè)備處于忙狀態(tài)時(shí),write調(diào)用將被阻塞并被延遲執(zhí)行調(diào)用將被阻塞并被延遲執(zhí)行u 當(dāng)當(dāng)write調(diào)用完成時(shí),都能返回實(shí)際寫入的字節(jié)數(shù)調(diào)用完成時(shí),都能返回實(shí)際寫入的字節(jié)數(shù)u 對(duì)管道讀時(shí),所有的對(duì)管道讀時(shí),所有的read操作總是從管道的當(dāng)前位置開(kāi)始,操作總是從管道的當(dāng)前位置開(kāi)始,即是管道文件不支持指針
32、的移動(dòng),而文件的讀不遵守這個(gè)規(guī)定,即是管道文件不支持指針的移動(dòng),而文件的讀不遵守這個(gè)規(guī)定,它可以通過(guò)指針隨意移動(dòng)它可以通過(guò)指針隨意移動(dòng) (b)管道讀和一般文件讀)管道讀和一般文件讀(read)u 當(dāng)管道中沒(méi)有信息時(shí),對(duì)管道進(jìn)行當(dāng)管道中沒(méi)有信息時(shí),對(duì)管道進(jìn)行read操作將被阻塞,直操作將被阻塞,直到有數(shù)據(jù)才返回;而對(duì)空文件進(jìn)行到有數(shù)據(jù)才返回;而對(duì)空文件進(jìn)行read操作,可以返回空串,操作,可以返回空串,并不發(fā)生阻塞并不發(fā)生阻塞 為了創(chuàng)建無(wú)名管道,需要調(diào)用為了創(chuàng)建無(wú)名管道,需要調(diào)用pipe函數(shù)函數(shù),pipe函數(shù)建立一個(gè)管函數(shù)建立一個(gè)管道,使得兩個(gè)進(jìn)程可經(jīng)由它相互傳遞信息。我們可以將管道視為一道,使
33、得兩個(gè)進(jìn)程可經(jīng)由它相互傳遞信息。我們可以將管道視為一塊空間,進(jìn)程可以經(jīng)由兩個(gè)不同的文件描述符來(lái)分享這塊空間;同塊空間,進(jìn)程可以經(jīng)由兩個(gè)不同的文件描述符來(lái)分享這塊空間;同時(shí)時(shí)pipe函數(shù)產(chǎn)生兩個(gè)文件描述字,進(jìn)程通過(guò)使用這兩個(gè)文件描述字函數(shù)產(chǎn)生兩個(gè)文件描述字,進(jìn)程通過(guò)使用這兩個(gè)文件描述字來(lái)存取管道信息來(lái)存取管道信息1 創(chuàng)建無(wú)名管道創(chuàng)建無(wú)名管道#include int pipe( int fdes2 );pipe函數(shù)的唯一參數(shù)是一個(gè)由兩個(gè)整數(shù)組成的數(shù)組,該函數(shù)調(diào)用成函數(shù)的唯一參數(shù)是一個(gè)由兩個(gè)整數(shù)組成的數(shù)組,該函數(shù)調(diào)用成功后將含有作為管道使用的兩個(gè)文字描述符,一個(gè)作為管道的輸入,功后將含有作為管道使用
34、的兩個(gè)文字描述符,一個(gè)作為管道的輸入,另一個(gè)作為管道的輸出。另一個(gè)作為管道的輸出。 2 管道讀寫操作管道讀寫操作讀操作讀操作 int read( int fd, char *buf, int len );寫操作寫操作 int write( int fd, char *buf, int len );u 用用pipe函數(shù)創(chuàng)建的管道沒(méi)有名字,是為了一次使用而創(chuàng)建的函數(shù)創(chuàng)建的管道沒(méi)有名字,是為了一次使用而創(chuàng)建的3 管道操作特點(diǎn)管道操作特點(diǎn)u 管道的兩個(gè)描述字管道的兩個(gè)描述字fdes0和和fdes1是同時(shí)打開(kāi)的,如果從一是同時(shí)打開(kāi)的,如果從一個(gè)沒(méi)有任何進(jìn)程寫入的管道讀,個(gè)沒(méi)有任何進(jìn)程寫入的管道讀,rea
35、d將返回將返回EOF(文件結(jié)束)。如(文件結(jié)束)。如果向一個(gè)沒(méi)有任何進(jìn)程讀取的管道寫數(shù)據(jù),將產(chǎn)生果向一個(gè)沒(méi)有任何進(jìn)程讀取的管道寫數(shù)據(jù),將產(chǎn)生SIGPIPE信號(hào)信號(hào)u 對(duì)有效的管道進(jìn)行對(duì)有效的管道進(jìn)行write操作時(shí),如果管道已滿,操作時(shí),如果管道已滿,write函數(shù)將被函數(shù)將被阻塞,直到有數(shù)據(jù)被讀出。阻塞,直到有數(shù)據(jù)被讀出。u 對(duì)有效的管道進(jìn)行對(duì)有效的管道進(jìn)行read操作時(shí),如果管道內(nèi)沒(méi)有數(shù)據(jù),操作時(shí),如果管道內(nèi)沒(méi)有數(shù)據(jù),read函函數(shù)將被阻塞,直到有新數(shù)據(jù)到達(dá)為止。數(shù)將被阻塞,直到有新數(shù)據(jù)到達(dá)為止。u 管道內(nèi)的數(shù)據(jù)只能被讀出管道內(nèi)的數(shù)據(jù)只能被讀出1次次u 管道不允許進(jìn)行文件的定位操作,讀和寫
36、操作都是順序的管道不允許進(jìn)行文件的定位操作,讀和寫操作都是順序的4 例程例程 :最簡(jiǎn)單的管道通信:最簡(jiǎn)單的管道通信void main() int fd2, pid; char msgsend = “Hi! Kid .n”; char msgrecv32; if( pipe( fd ) = -1 ) exit(1); if( (pid=fork() = 0 ) /pid =0 子進(jìn)程子進(jìn)程 close( fd1 ); printf(“before read data from pipe!n”); read( fd0, msgrecv, strlen(msgsend); printf(“read
37、%s from pipen”, msgrecv); else /父進(jìn)程父進(jìn)程 close( fd0 ); printf(“Parent sleeping .”); sleep(3); / 迫使子進(jìn)程先執(zhí)行迫使子進(jìn)程先執(zhí)行 printf(“Parent wake up !n”); write( fd1, msgsend, strlen(msgsend) ); wait(); exit(0); 基本上,無(wú)名管道只能在父子進(jìn)程之間進(jìn)行通信,兩個(gè)沒(méi)有父子關(guān)基本上,無(wú)名管道只能在父子進(jìn)程之間進(jìn)行通信,兩個(gè)沒(méi)有父子關(guān)系的進(jìn)程,將不能使用這種方式進(jìn)行通信;因此在無(wú)名管道的基礎(chǔ)上,系的進(jìn)程,將不能使用這種方式
38、進(jìn)行通信;因此在無(wú)名管道的基礎(chǔ)上,UNIX系統(tǒng)引入了有名管道的方式系統(tǒng)引入了有名管道的方式1.使用命令創(chuàng)建有名管道使用命令創(chuàng)建有名管道UNIX系統(tǒng)中有兩個(gè)命令可以創(chuàng)建有名管道系統(tǒng)中有兩個(gè)命令可以創(chuàng)建有名管道%mknod myfifo p或者或者%mkfifo a=rw myfifo%ls l myfifoprw-rw-rw- 1 lisi user 0 Nov 27 18:30 myfifop表示該文件為有名管道文件表示該文件為有名管道文件2.使用命令操作有名管道使用命令操作有名管道有名管道建立后,可以使用一些普通的命令對(duì)它進(jìn)行操作,如果一有名管道建立后,可以使用一些普通的命令對(duì)它進(jìn)行操作,如
39、果一般的文件操作一樣般的文件操作一樣%cat cfile.c myfifo &將文件將文件cfile.c中的內(nèi)容傳遞到有名管道中的內(nèi)容傳遞到有名管道m(xù)yfifo中中% cat myfifo將有名管道將有名管道m(xù)yfifo中的內(nèi)容讀出,并顯示在標(biāo)準(zhǔn)輸出上中的內(nèi)容讀出,并顯示在標(biāo)準(zhǔn)輸出上3.使用函數(shù)創(chuàng)建有名管道使用函數(shù)創(chuàng)建有名管道#include #include int mkfifo( char *path, mode_t mode );int mknod( char *path, mode_t mode, dev_t dev );int mkfifo( “/home/user1/myf
40、ifo”, 0666 );int mknod( “/home/user1/myfifo”, 0666|S_IFIFO, 0);對(duì)有名管道進(jìn)行讀寫操作前必須使用對(duì)有名管道進(jìn)行讀寫操作前必須使用open函數(shù)打開(kāi)管道文件函數(shù)打開(kāi)管道文件其他相關(guān)函數(shù)其他相關(guān)函數(shù)int open(const char* filename,int flags,mode_t mode); open函數(shù)不能以函數(shù)不能以O(shè)_RDWR方式打開(kāi)方式打開(kāi) open函數(shù)可以指定函數(shù)可以指定O_NONBLOCK非阻塞標(biāo)志非阻塞標(biāo)志int read( int fd, char *buf, int len );int write( int
41、fd, char *buf, int len );int close (int fd);A.客戶端進(jìn)程完成的工作客戶端進(jìn)程完成的工作 1.建立私有有名管道建立私有有名管道 2.打開(kāi)服務(wù)端的共有有名管道打開(kāi)服務(wù)端的共有有名管道 3.等待用戶輸入命令等待用戶輸入命令 4.將私有管道名和命令寫入公有管道將私有管道名和命令寫入公有管道 5.從私有管道中讀服務(wù)端返回的結(jié)果從私有管道中讀服務(wù)端返回的結(jié)果5.例程例程 :一個(gè)基于有名管道的:一個(gè)基于有名管道的C/S模式應(yīng)用,客戶端發(fā)送命令到服務(wù)器,服模式應(yīng)用,客戶端發(fā)送命令到服務(wù)器,服務(wù)器執(zhí)行命令,并將命令返回信息回傳給客戶端務(wù)器執(zhí)行命令,并將命令返回信息回
42、傳給客戶端B.服務(wù)端進(jìn)程完成的工作服務(wù)端進(jìn)程完成的工作 1.建立服務(wù)端公有有名管道建立服務(wù)端公有有名管道 2.從公有有名管道中讀取客戶數(shù)據(jù)從公有有名管道中讀取客戶數(shù)據(jù) 3.執(zhí)行命令,并將結(jié)果寫入客戶私有管道執(zhí)行命令,并將結(jié)果寫入客戶私有管道#include FILE * popen(char *command, char *mode);該函數(shù)類似于該函數(shù)類似于system函數(shù),它調(diào)用函數(shù),它調(diào)用command參數(shù)指定的命令,并返回參數(shù)指定的命令,并返回指向命令執(zhí)行結(jié)果信息的文件句柄。指向命令執(zhí)行結(jié)果信息的文件句柄。跟例程相關(guān)的兩個(gè)函數(shù)跟例程相關(guān)的兩個(gè)函數(shù)#include FILE * pclo
43、se(FILE *fp);該函數(shù)關(guān)閉由該函數(shù)關(guān)閉由popen函數(shù)返回的文件句柄函數(shù)返回的文件句柄/客戶端代碼客戶端代碼#define PUBLIC /tmp/publicstruct message char fifo_name256; char cmd_line4096;void main() int n,privatefifo, publicfifo; char buffer4096; struct message msg; sprintf(msg.fifo_name, /tmp/fifo%d, getpid(); if( mknod(msg.fifo_name, S_IFIFO|0666
44、, 0) 0 ) / 打開(kāi)客戶端建立的私有管道并準(zhǔn)備寫入數(shù)據(jù)打開(kāi)客戶端建立的私有管道并準(zhǔn)備寫入數(shù)據(jù) privatefifo = open(msg.fifo_name, O_WRONLY | O_NDELAY ); if( privatefifo = -1 ) 錯(cuò)誤處理錯(cuò)誤處理 fin = popen(msg.cmd_line, “r”); /執(zhí)行命令執(zhí)行命令 while( n = read(fileno(fin), buffer, 4096) 0 ) write(privatefifo, buffer, n); /將從將從fin讀到的數(shù)據(jù)寫入客戶的私有管道讀到的數(shù)據(jù)寫入客戶的私有管道 mems
45、et(buffer, 0, 4096); pclose(fin); 4.有名管道和無(wú)名管道的區(qū)別有名管道和無(wú)名管道的區(qū)別特性特性有名管道有名管道無(wú)名管道無(wú)名管道進(jìn)程的使用資格進(jìn)程的使用資格沒(méi)有限制沒(méi)有限制必須有父子關(guān)系必須有父子關(guān)系文件名稱文件名稱有文件名,可以用有文件名,可以用ls l查看,查看,其文件屬性為其文件屬性為p沒(méi)有文件名稱沒(méi)有文件名稱數(shù)據(jù)讀寫的次序數(shù)據(jù)讀寫的次序先進(jìn)先出先進(jìn)先出先進(jìn)先出先進(jìn)先出建立的方式建立的方式使用使用mkfifo或者或者mknod函數(shù)函數(shù)使用使用pipe函數(shù)函數(shù)刪除的方式刪除的方式使用使用rm命令或者命令或者unlink函數(shù)函數(shù)被使用完后,會(huì)被自動(dòng)刪除被使用完
46、后,會(huì)被自動(dòng)刪除 在在IPC (Interprocess communication)的通信模式通常有三種:消息的通信模式通常有三種:消息隊(duì)列、信號(hào)量、共享內(nèi)存。隊(duì)列、信號(hào)量、共享內(nèi)存。消息隊(duì)列方式消息隊(duì)列方式:使用一個(gè)消息結(jié)構(gòu)完成進(jìn)程間分類格式化數(shù):使用一個(gè)消息結(jié)構(gòu)完成進(jìn)程間分類格式化數(shù)據(jù)的傳送據(jù)的傳送共享存儲(chǔ)區(qū)方式共享存儲(chǔ)區(qū)方式:允許進(jìn)程間共享:允許進(jìn)程間共享 虛地址空間的某些區(qū)域,虛地址空間的某些區(qū)域,以達(dá)到信息傳送的效果以達(dá)到信息傳送的效果信號(hào)量方式:信號(hào)量方式:允許進(jìn)程在一組信號(hào)量上進(jìn)行交互,完成同步允許進(jìn)程在一組信號(hào)量上進(jìn)行交互,完成同步地執(zhí)行地執(zhí)行UNIX系統(tǒng)中,可以使用系統(tǒng)中,
47、可以使用 ipcs命令得到當(dāng)前系統(tǒng)命令得到當(dāng)前系統(tǒng)IPC的所的所有信息有信息 在在IPC的通信模式下,每個(gè)的通信模式下,每個(gè)IPC對(duì)象有一個(gè)唯一的名字,稱之為對(duì)象有一個(gè)唯一的名字,稱之為“鍵鍵”(key)即關(guān)鍵字)即關(guān)鍵字, 類似于文件的文件描述符。類似于文件的文件描述符。 在在IPC的通信模式下,的通信模式下,key的使用使得一個(gè)的使用使得一個(gè)IPC對(duì)象為多個(gè)進(jìn)程所共用。對(duì)象為多個(gè)進(jìn)程所共用。不使用不使用key,進(jìn)程無(wú)法存取對(duì)象。,進(jìn)程無(wú)法存取對(duì)象。 IPC對(duì)象一旦被建立之后,即是全局的。對(duì)象一旦被建立之后,即是全局的。上面我們探討過(guò)信號(hào)的使用,下面介紹消息的運(yùn)用,先將他們進(jìn)行一下比較上面我
48、們探討過(guò)信號(hào)的使用,下面介紹消息的運(yùn)用,先將他們進(jìn)行一下比較特性特性信號(hào)信號(hào)消息消息數(shù)據(jù)內(nèi)容數(shù)據(jù)內(nèi)容只是一些預(yù)設(shè)好的代碼用以表示系只是一些預(yù)設(shè)好的代碼用以表示系統(tǒng)發(fā)生的某些狀況統(tǒng)發(fā)生的某些狀況為一組連續(xù)語(yǔ)句或者符號(hào),通為一組連續(xù)語(yǔ)句或者符號(hào),通常量不會(huì)太大常量不會(huì)太大(比如比如1024字節(jié)字節(jié))用途用途擔(dān)任進(jìn)程間少量信息的傳送,多半擔(dān)任進(jìn)程間少量信息的傳送,多半是核心程序用來(lái)通知用戶進(jìn)程一些是核心程序用來(lái)通知用戶進(jìn)程一些異常的狀況異常的狀況用于進(jìn)程之間彼此進(jìn)行數(shù)據(jù)交用于進(jìn)程之間彼此進(jìn)行數(shù)據(jù)交換換發(fā)送時(shí)刻發(fā)送時(shí)刻任何時(shí)間任何時(shí)間不是任何時(shí)刻都可以發(fā)送不是任何時(shí)刻都可以發(fā)送發(fā)送者辨識(shí)發(fā)送者辨識(shí)不知
49、道發(fā)送者是誰(shuí)不知道發(fā)送者是誰(shuí)明確知道發(fā)送者是誰(shuí)明確知道發(fā)送者是誰(shuí)送往對(duì)象送往對(duì)象某個(gè)進(jìn)程某個(gè)進(jìn)程消息隊(duì)列消息隊(duì)列處理方法處理方法可以處理或者不予理會(huì)可以處理或者不予理會(huì)必須要處理必須要處理數(shù)據(jù)傳輸效率數(shù)據(jù)傳輸效率不適合較大量的信息傳輸,效率差不適合較大量的信息傳輸,效率差對(duì)中等數(shù)量的數(shù)據(jù)傳送效率好對(duì)中等數(shù)量的數(shù)據(jù)傳送效率好 消息隊(duì)列使進(jìn)程能將格式化的數(shù)據(jù)送往任意的進(jìn)程。消息隊(duì)消息隊(duì)列使進(jìn)程能將格式化的數(shù)據(jù)送往任意的進(jìn)程。消息隊(duì)列主要由三部分組成:消息隊(duì)列表、消息頭、消息文本。列主要由三部分組成:消息隊(duì)列表、消息頭、消息文本。 其中消息隊(duì)列表中每個(gè)隊(duì)列項(xiàng)包含有該隊(duì)列的頭尾指針,描其中消息隊(duì)列表中
50、每個(gè)隊(duì)列項(xiàng)包含有該隊(duì)列的頭尾指針,描述了一個(gè)隊(duì)列的位置。述了一個(gè)隊(duì)列的位置。 消息頭表中包含所有消息隊(duì)列索引等信息。消息頭有指向消消息頭表中包含所有消息隊(duì)列索引等信息。消息頭有指向消息正文的指針。息正文的指針。 消息正文指存放真正消息的數(shù)據(jù)區(qū),即信息的實(shí)體。消息正文指存放真正消息的數(shù)據(jù)區(qū),即信息的實(shí)體。隊(duì)列1隊(duì)列2隊(duì)列3隊(duì)列nmessage10message11message1m消息正文消息正文消息正文 1 1 消息隊(duì)列的創(chuàng)建或獲取消息隊(duì)列的創(chuàng)建或獲取include include include int msgget(key_t key,int msgflg); 消息隊(duì)列的創(chuàng)建或獲取需要用到
51、消息隊(duì)列的創(chuàng)建或獲取需要用到msggetmsgget函數(shù)函數(shù)參數(shù)參數(shù)Key:Key:關(guān)鍵字值。關(guān)鍵字值。參數(shù)參數(shù)MsgflgMsgflg: :打開(kāi)和存取操作權(quán)限設(shè)置打開(kāi)和存取操作權(quán)限設(shè)置 IPC_CREATIPC_CREAT:如果內(nèi)核中沒(méi)有此隊(duì)列,則創(chuàng)建它。:如果內(nèi)核中沒(méi)有此隊(duì)列,則創(chuàng)建它。 IPC_EXCLIPC_EXCL和和IPC_CREATIPC_CREAT一起使用時(shí),如果隊(duì)列已經(jīng)存在,則失敗一起使用時(shí),如果隊(duì)列已經(jīng)存在,則失敗1.1.消息隊(duì)列的創(chuàng)建示例消息隊(duì)列的創(chuàng)建示例 int msgid; key_t key=56789; msgid = msgget( key, 0666 ); /
52、打開(kāi)一個(gè)關(guān)鍵字為打開(kāi)一個(gè)關(guān)鍵字為56789的消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,的消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,則函數(shù)返回該消息隊(duì)列的則函數(shù)返回該消息隊(duì)列的id,如果該隊(duì)列不存在,則函數(shù)返回,如果該隊(duì)列不存在,則函數(shù)返回錯(cuò)錯(cuò) int msgid; key_t key=56789; msgid = msgget( key, IPC_CREAT|IPC_EXCL|0666 ); /創(chuàng)建一個(gè)關(guān)鍵字為創(chuàng)建一個(gè)關(guān)鍵字為56789的消息隊(duì)列,并設(shè)置權(quán)限為的消息隊(duì)列,并設(shè)置權(quán)限為0666,即是所有,即是所有用戶都能讀和寫該消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,則函數(shù)返回錯(cuò)誤用戶都能讀和寫該消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,則
53、函數(shù)返回錯(cuò)誤-1 int msgid; key_t key=56789; msgid = msgget( key, IPC_CREAT|0666 ); /創(chuàng)建一個(gè)關(guān)鍵字為創(chuàng)建一個(gè)關(guān)鍵字為56789的消息隊(duì)列,并設(shè)置權(quán)限為的消息隊(duì)列,并設(shè)置權(quán)限為0666,即,即是所有用戶都能讀和寫該消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,則直接是所有用戶都能讀和寫該消息隊(duì)列,如果該隊(duì)列已經(jīng)存在,則直接得到其隊(duì)列的標(biāo)識(shí)得到其隊(duì)列的標(biāo)識(shí)id2.2.消息發(fā)送消息發(fā)送include include include int msgsnd(int msgid,const void *msgp,size_t msgsz int msg
54、flg);消息發(fā)送需要用到函數(shù)消息發(fā)送需要用到函數(shù)msgsndmsgsnd返回值:如果成功,返回值:如果成功,0 0;如果失敗,;如果失敗,-1-1參數(shù)參數(shù)msgidmsgid是消息隊(duì)列標(biāo)識(shí)符,它是由系統(tǒng)調(diào)用是消息隊(duì)列標(biāo)識(shí)符,它是由系統(tǒng)調(diào)用msggetmsgget返回的。返回的。參數(shù)參數(shù)msgpmsgp,是指向消息緩沖區(qū)的指針。,是指向消息緩沖區(qū)的指針。參數(shù)參數(shù)msgszmsgsz中包含的是消息的字節(jié)大小中包含的是消息的字節(jié)大小 參數(shù)參數(shù)msgflgmsgflg可以設(shè)置為可以設(shè)置為0 0(此時(shí)為忽略此參數(shù)),或者使用(此時(shí)為忽略此參數(shù)),或者使用IPC_NOWAITIPC_NOWAIT如果消息
55、隊(duì)列已滿,那么此消息則不會(huì)寫入到消息隊(duì)列中,控制將返回到調(diào)用進(jìn)程中。如果沒(méi)有指明,調(diào)用進(jìn)程將會(huì)掛起,直到消息可以寫入到隊(duì)列中。3.3.消息接收消息接收include include include Int msgrcv(int msqid,struct msgbuf Int msgrcv(int msqid,struct msgbuf * *msgp,int msgsz,long mtype,int msgflgmsgp,int msgsz,long mtype,int msgflg););消息接收需要用到函數(shù)消息接收需要用到函數(shù)msgrcvmsgrcv返回值:如果成功,則返回復(fù)制到消息緩沖區(qū)
56、的字節(jié)數(shù)。如果失敗,則返回-1參數(shù)參數(shù)msgidmsgid用來(lái)指定將要讀取消息的隊(duì)列。用來(lái)指定將要讀取消息的隊(duì)列。參數(shù)參數(shù)msgpmsgp代表要存儲(chǔ)消息的消息緩沖區(qū)的地址。代表要存儲(chǔ)消息的消息緩沖區(qū)的地址。參數(shù)參數(shù)msgszmsgsz是消息緩沖區(qū)的長(zhǎng)度,不包括是消息緩沖區(qū)的長(zhǎng)度,不包括mtypemtype的長(zhǎng)度,它可以按照如下的方的長(zhǎng)度,它可以按照如下的方法計(jì)算:法計(jì)算:msgsz=sizeof(structmymsgbuf)-sizeof(longmsgsz=sizeof(structmymsgbuf)-sizeof(long););參數(shù)參數(shù)msgflgmsgflg是要從消息隊(duì)列中讀取的消息
57、的類型。如果此參數(shù)的值為是要從消息隊(duì)列中讀取的消息的類型。如果此參數(shù)的值為0 0,那么,那么隊(duì)列中最長(zhǎng)時(shí)間的一條消息將返回。隊(duì)列中最長(zhǎng)時(shí)間的一條消息將返回。如果調(diào)用中使用了IPC_NOWAIT作為標(biāo)志,那么當(dāng)沒(méi)有數(shù)據(jù)可以使用時(shí),調(diào)用將把ENOMSG返回到調(diào)用進(jìn)程中。否則,調(diào)用進(jìn)程將會(huì)掛起,直到隊(duì)列中的一條消息滿足msgrcv()的參數(shù)要求。如果當(dāng)客戶端等待一條消息的時(shí)候隊(duì)列為空,將會(huì)返回EIDRM。如果進(jìn)程在等待消息的過(guò)程中捕捉到一個(gè)信號(hào),則返回EINTR4.4.消息隊(duì)列的控制消息隊(duì)列的控制include include include int msgctl(int msgid,int cmd
58、,struct msqid_ds *buf); UNIX UNIX系統(tǒng)提供系統(tǒng)提供 msgctlmsgctl函數(shù)實(shí)現(xiàn)對(duì)消息隊(duì)列的控制函數(shù)實(shí)現(xiàn)對(duì)消息隊(duì)列的控制IPC_STAT:讀取消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)msqid_ds,并將其存儲(chǔ)在buf指定的地址中。IPC_SET設(shè)置消息隊(duì)列的數(shù)據(jù)結(jié)構(gòu)msqid_ds中的ipc_perm元素的值。這個(gè)值取自buf參數(shù)。IPC_RMID從系統(tǒng)內(nèi)核中移走消息隊(duì)列。3.3.示例示例1 1有兩個(gè)程序有兩個(gè)程序program1program1和和program2,program2,其中其中program2program2接受用戶輸入,并將輸入內(nèi)容發(fā)接受用戶輸入,并將輸入內(nèi)容
59、發(fā)送到送到program1program1,program1program1顯示接收到的消息。顯示接收到的消息。 如果用戶輸入如果用戶輸入endend,則兩個(gè)程序都,則兩個(gè)程序都結(jié)束結(jié)束/ program1.cinclude include include struct my_msg long mytype; char text256;void main() int running = 1; int msgid; struct my_msg msgbuf; msgid = msgget( ( key_t )1234, IPC_CREAT|0666 ); if( msgid 0 ) exit(1
60、); while( running ) if( msgrcv( msgid, (void *)&msgbuf, 256, 1, 0) = -1) / 錯(cuò)誤處理錯(cuò)誤處理 printf(“you wrote: %s”, msgbuf.text ); if( strncmp( msgbuf.txt, “end” , 3 ) = = 0 ) running = 0; if( msgctl( msgid, IPC_RMID, 0 ) = -1 ) / 錯(cuò)誤處理錯(cuò)誤處理 exit( 0 );/ program2.cinclude include include struct my_msg long mytype; char text256;void main() int running = 1; int msgid; struct my_msg msgb
溫馨提示
- 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。
最新文檔
- 電子圖書出版與運(yùn)營(yíng)手冊(cè)
- 房屋租賃三方合同格式
- 焊接工藝與材料選擇作業(yè)指導(dǎo)書
- 成本合同管理大全
- 生物科技居間合同協(xié)議書
- 有關(guān)事業(yè)單位合同
- 2025年呼和浩特貨運(yùn)從業(yè)資格證模擬考試題下載
- 2025年南昌從業(yè)資格貨運(yùn)資格考試題庫(kù)答案解析
- 2025年龍巖a2駕駛證貨運(yùn)從業(yè)資格證模擬考試
- 電力市場(chǎng)策略合同(2篇)
- 跨領(lǐng)域安檢操作標(biāo)準(zhǔn)化的現(xiàn)狀與挑戰(zhàn)
- 2024年08月香港2024年中國(guó)銀行(香港)有限公司校園招考筆試歷年參考題庫(kù)附帶答案詳解
- 大模型落地應(yīng)用實(shí)踐方案
- 2025年重慶三峽擔(dān)保集團(tuán)招聘筆試參考題庫(kù)含答案解析
- 2025年八省聯(lián)考內(nèi)蒙古高考生物試卷真題答案詳解(精校打印)
- 地下室頂板后澆帶混凝土構(gòu)造柱支撐方案
- GB/T 19799.2-2024無(wú)損檢測(cè)超聲檢測(cè)試塊第2部分:2號(hào)標(biāo)準(zhǔn)試塊
- 2024山東一卡通文化旅游一卡通合作協(xié)議3篇
- GB/T 45091-2024塑料再生塑料限用物質(zhì)限量要求
- 人教版八年級(jí)上冊(cè)地理 2024-2025學(xué)年八年級(jí)上冊(cè)地理期中測(cè)試卷(二)(含答案)
- 2025屆高三歷史二輪復(fù)習(xí)教學(xué)計(jì)劃
評(píng)論
0/150
提交評(píng)論