QNX IPC機制

QNX相關歷史文章:

介紹

Interprocess Communication(IPC狮惜,進程間通信)在QNX Neutrino從一個嵌入式實時系統(tǒng)向一個全面的POSIX系統(tǒng)轉變起著至關重要的作用。IPC是將在內核中提供各種服務的進程內聚在一起的粘合劑。在QNX中衔沼,消息傳遞是IPC的主要形式新蟆,也提供了其他的形式,除非有特殊的說明媚狰,否則這些形式也都是基于本地消息傳遞而實現的溪胶。QNX Neutrino提供以下形式的IPC:


IPC

Synchronous message passing

一個線程調用MsgSend()往目標線程發(fā)送消息時會阻塞住躯嫉,直到目標線程調用MsgReceive()纱烘,進行消息處理并調用MsgReply()回復后才會解除阻塞。
在QNX Neutrino中祈餐,服務器線程通常是循環(huán)的擂啥,等待接收客戶端發(fā)過來的消息》簦可以看看客戶端線程和服務器線程在消息傳遞過程中的狀態(tài)變化:

  1. 客戶端線程
  • 客戶端線程調用MsgSend()后哺壶,如果服務器線程還沒調用MsgReceive(),客戶端線程狀態(tài)則為SEND blocked蜒谤,一旦服務器線程調用了MsgReceive()山宾,客戶端線程狀態(tài)變?yōu)?code>REPLY blocked,當服務器線程執(zhí)行MsgReply()后鳍徽,客戶端線程狀態(tài)就變成了READY资锰;
  • 如果客戶端線程調用MsgSend()后,而服務器線程正阻塞在MsgReceive()上阶祭, 則客戶端線程狀態(tài)直接跳過SEND blocked绷杜,直接變成REPLY blocked
  • 當服務器線程失敗濒募、退出鞭盟、或者消失了,客戶端線程狀態(tài)變成READY瑰剃,此時MsgSend()會返回一個錯誤值齿诉。
  1. 服務器線程
  • 服務器線程調用MsgReceive()時,當沒有線程給它發(fā)送消息培他,它的狀態(tài)為RECEIVE blocked鹃两,當有線程發(fā)送時變?yōu)?code>READY;
  • 服務器線程調用MsgReceive()時舀凛,當已經有其他線程給它發(fā)送過消息俊扳,MsgReceive()會立馬返回,而不會阻塞猛遍;
  • 服務器線程調用MsgReply()時馋记,不會阻塞号坡;

Message copying

QNX的消息服務,是直接將消息從一個線程的地址空間拷貝到另一個線程地址空間梯醒,不需要中間緩沖宽堆,因此消息傳遞的性能接近底層硬件的內存帶寬。消息內容對內核來說沒有特殊的意義茸习,只對消息的發(fā)送和接收者才有意義畜隶,當然,QNX也提供了定義良好的消息類型号胚,以便能擴充或替代系統(tǒng)提供的服務籽慢。
消息在拷貝的時候,支持分塊傳輸猫胁,也就是不要求連續(xù)的緩沖區(qū)箱亿,發(fā)送和接收線程可以指定向量表,在這個表中去指定消息在內存中的位置弃秆。這個與DMA的scatter/gather機制類似届惋。

multipart transfer

分塊傳輸也用在文件系統(tǒng)中,比如讀數據的時候菠赚,將文件系統(tǒng)緩存中的數據分塊讀到用戶提供的空間內脑豹,如下圖:


對于簡單的單塊消息傳遞,就不需要通過IOV(input/output vector)的形式了衡查,直接指向緩沖區(qū)即可晨缴。對于發(fā)送和接收的接口,多塊發(fā)送和單塊發(fā)送如下:


Channels and connections

在QNX Neutrino中峡捡,消息傳遞是面向通道(channel)和連接(connection)的击碗,而不是直接從線程到線程的。接收消息的線程需要創(chuàng)建一個channel们拙,發(fā)送消息的線程需要與該channel建立connection稍途。
服務器使用MsgReceive()接收消息時需要使用channels,客戶端則需要創(chuàng)建connections砚婆,以連接到服務器的通道上械拍,連接建立好之后,客戶端便可通過MsgSend()來發(fā)送消息了装盯。如果進程中有很多線程都連接到一個通道上坷虑,為了提高效率,這些所有的連接都會映射到同一個內核對象中埂奈。在進程中迄损,channelsconnecttions會用一個小的整型標識符來標記≌嘶牵客戶端connections會直接映射到文件描述符芹敌,在架構上這是一個關鍵點痊远,可以消除另一層轉換,不需要根據文件描述符來確定往哪里發(fā)消息氏捞,而是直接將消息發(fā)往文件描述符即可碧聪。


Connections map elegantly into file descriptors

有幾個與channel有關聯(lián)的列表:

  • Receive,等待消息的LIFO線程隊列液茎;
  • Send逞姿,已發(fā)送消息但還未被接收的優(yōu)先級FIFO線程隊列;
  • Reply捆等, 已發(fā)送消息哼凯,并且已經被收到,但尚未回復的無序線程列表楚里;
    不管在上述哪個列表中,線程都是阻塞狀態(tài)猎贴,多個線程和多個客戶端可能等待在同一個channel上班缎。
    threads blocked while in a channel queue

Pulses

除了同步發(fā)送/接收/回復服務外,QNX還支持固定大小的非阻塞消息她渴,這種消息被稱為Pulse达址,攜帶一個小的負載(四個字節(jié)數據,加一個字節(jié)的代碼)趁耗。Pulse通常被用在中斷處理函數中沉唠,用作通知機制;也允許服務器在不阻塞客戶端的情況下苛败,向客戶端發(fā)送信號满葛。

Pulses pack a small payload

優(yōu)先級繼承與消息

服務器進程按照優(yōu)先級順序來接收消息和脈沖,當服務器中的線程接收請求時罢屈,它們將繼承發(fā)送線程的優(yōu)先級嘀韧。請求服務器工作的線程的優(yōu)先級被保留,服務器工作將以適當的優(yōu)先級執(zhí)行缠捌,這種消息驅動的優(yōu)先級繼承避免了優(yōu)先級反轉的問題锄贷。

Message-passing API

Robust implementations with Send/Receive/Reply

異步系統(tǒng)的一個重要問題是事件通知需要運行信號處理程序。異步IPC難以徹底對系統(tǒng)進行測試曼月,此外也難以確保信號處理程序按預期的運行谊却。基于Send/Receive/Reply構建的同步哑芹、非隊列系統(tǒng)結構炎辨,可以讓應用程序的架構更健壯。

在使用各種IPC機制時聪姿,避免死鎖是一個難題蹦魔,在QNX中只需要遵循兩個原則激率,就可以構建無死鎖系統(tǒng):

  • 永遠不要兩個線程相互發(fā)送消息;
  • 將線程組織為層級結構勿决,并只向上發(fā)送消息乒躺;
    Threads should always send up to higher-level threads

    上層的線程可以通過MsgSendPulse()MsgDeliverEvent()來傳遞非阻塞消息或事件:
    A higher-level thread can "send" a pulse event

Events

QNX Neutrino提供異步事件通知機制,事件源可能有三種:

  • 調用MsgDeliverEvent()接口發(fā)送事件
  • 中斷處理函數
  • 定時器到期
    事件本身可以有多種類型:Pulse低缩、中斷嘉冒、各種形式的信號、強制解除阻塞的事件等咆繁。
    考慮到事件本身的多樣性讳推,服務器實現所有的異步通知顯然不太合適,更好的方式是客戶端提供一個數據結構或者cookie玩般,服務器調用MsgDeliverEvent()時將事件類型寫進cookie中银觅。
    The client sends a sigevent to the server

ionotify()函數是客戶端線程請求異步事件通知的一種方式,許多POSIX異步服務都基于這個之上來構建的坏为,比如mq_notifyselect等究驴。

Signals

信號類似于軟中斷,QNX支持的信號如下:


QNX Neutrino擴展了信號傳遞機制匀伏,允許信號針對特定的線程洒忧,而不是簡單的針對包含線程的進程。由于信號是異步事件够颠,它們通過事件傳遞機制實現熙侍。接口如下:


Signal delivery

當一個服務器線程想通知一個客戶端線程時,有兩種合理的事件選擇:Pulse或信號

  • Pulse履磨,需要客戶端創(chuàng)建一個channel蛉抓,并且調用MsgReceive()接收;
  • 信號剃诅,只需要調用sigwaitinfo()芝雪,不需要創(chuàng)建channel

POSIX message queues

POSIX通過message queues定義一組非阻塞的消息傳遞機制综苔。消息隊列為命名對象惩系,針對這些對象可以進行讀取和寫入,作為離散消息的優(yōu)先級隊列如筛,消息隊列具有比管道更多的結構堡牡,為應用程序提供了更多的通信控制。QNX Neutrino內核不包含message queues杨刨,它的實現在內核之外晤柄。
QNX Neutrino提供了兩種message queues的實現:

  • mqueue,使用mqueue資源管理的傳統(tǒng)實現
  • mq妖胀,使用mq服務和非同步消息的替代實現

QNX消息機制與POSIX的Message queues有一個根本的區(qū)別:芥颈,QNX的消息機制通過內存拷貝來實現消息的傳遞惠勒;而POSIX的消息隊列通過將消息進行存取來實現消息的傳遞。QNX的消息機制比POSIX的消息隊列效率更高爬坑,但有時為了POSIX的靈活纠屋,需要適當的犧牲一點效率。

消息隊列與文件類似盾计,操作的接口相近售担。


Shared memory

共享內存提供了最高帶寬的IPC機制,一旦創(chuàng)建了共享內存對象署辉,訪問對象的進程可以使用指針直接對其進行讀寫操作族铆。共享內存本身是不同步的,需要結合同步原語一起使用哭尝,信號量和互斥鎖都適合與共享內存一塊使用哥攘,信號量一般用于進程之間的同步,而互斥鎖通常用于線程之間的同步材鹦,通通常來說互斥鎖的效率會比信號量要高逝淹。

共享內存與消息傳遞結合起來的IPC機制,可以提供以下特點:

  • 非常高的性能(共享內存)
  • 同步(消息傳遞)
  • 跨網絡傳遞(消息傳遞)

QNX中消息傳遞通過拷貝完成侠姑,當消息較大時,可以通過共享內存來完成箩做,發(fā)送消息時不需要發(fā)送整個消息內容莽红,只需將消息保存到共享內存中,并將地址傳遞過去即可邦邦。


通常會使用mmap來將共享內存區(qū)域映射到進程地址空間中來安吁,如下圖所示:


Arguments to mmap

Typed memory

類型化內存是POSIX規(guī)范中定義的功能,它是高級實時擴展的一部分燃辖。
POSIX類型化內存鬼店,提供了一個接口來打開內存對象(以操作系統(tǒng)特定的方式定義),并對它們執(zhí)行映射操作黔龟。這個對提供BSP/板級特定的地址布局與設備驅動或用戶代碼之間的抽象時非常有用妇智。

Pipes and FIFOs

管道是一種非命名IO通道,用于在多個進程之間的通信氏身,一個進程往管道寫巍棱,其他進程從管道讀取。管道一般用于平行的兩個進程單向的傳遞數據蛋欣,如果要雙向通信的話航徙,就應該使用消息傳遞了。

FIFOs與管道本質是一樣的陷虎,不同點在于FIFOs會在文件系統(tǒng)中保存為一個永久的命名文件到踏。

?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末杠袱,一起剝皮案震驚了整個濱河市,隨后出現的幾起案子窝稿,更是在濱河造成了極大的恐慌楣富,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,183評論 6 516
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件讹躯,死亡現場離奇詭異菩彬,居然都是意外死亡,警方通過查閱死者的電腦和手機潮梯,發(fā)現死者居然都...
    沈念sama閱讀 94,850評論 3 399
  • 文/潘曉璐 我一進店門骗灶,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人秉馏,你說我怎么就攤上這事耙旦。” “怎么了萝究?”我有些...
    開封第一講書人閱讀 168,766評論 0 361
  • 文/不壞的土叔 我叫張陵免都,是天一觀的道長。 經常有香客問我帆竹,道長绕娘,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,854評論 1 299
  • 正文 為了忘掉前任栽连,我火速辦了婚禮险领,結果婚禮上,老公的妹妹穿的比我還像新娘秒紧。我一直安慰自己绢陌,他們只是感情好,可當我...
    茶點故事閱讀 68,871評論 6 398
  • 文/花漫 我一把揭開白布熔恢。 她就那樣靜靜地躺著脐湾,像睡著了一般。 火紅的嫁衣襯著肌膚如雪叙淌。 梳的紋絲不亂的頭發(fā)上秤掌,一...
    開封第一講書人閱讀 52,457評論 1 311
  • 那天,我揣著相機與錄音鹰霍,去河邊找鬼机杜。 笑死,一個胖子當著我的面吹牛衅谷,可吹牛的內容都是我干的椒拗。 我是一名探鬼主播,決...
    沈念sama閱讀 40,999評論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼蚀苛!你這毒婦竟也來了在验?” 一聲冷哼從身側響起,我...
    開封第一講書人閱讀 39,914評論 0 277
  • 序言:老撾萬榮一對情侶失蹤堵未,失蹤者是張志新(化名)和其女友劉穎腋舌,沒想到半個月后,有當地人在樹林里發(fā)現了一具尸體渗蟹,經...
    沈念sama閱讀 46,465評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡块饺,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 38,543評論 3 342
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現自己被綠了雌芽。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片授艰。...
    茶點故事閱讀 40,675評論 1 353
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖世落,靈堂內的尸體忽然破棺而出淮腾,到底是詐尸還是另有隱情,我是刑警寧澤屉佳,帶...
    沈念sama閱讀 36,354評論 5 351
  • 正文 年R本政府宣布谷朝,位于F島的核電站,受9級特大地震影響武花,放射性物質發(fā)生泄漏圆凰。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 42,029評論 3 335
  • 文/蒙蒙 一体箕、第九天 我趴在偏房一處隱蔽的房頂上張望专钉。 院中可真熱鬧,春花似錦干旁、人聲如沸驶沼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,514評論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至大年,卻和暖如春换薄,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背翔试。 一陣腳步聲響...
    開封第一講書人閱讀 33,616評論 1 274
  • 我被黑心中介騙來泰國打工轻要, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人垦缅。 一個月前我還...
    沈念sama閱讀 49,091評論 3 378
  • 正文 我出身青樓冲泥,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子凡恍,可洞房花燭夜當晚...
    茶點故事閱讀 45,685評論 2 360

推薦閱讀更多精彩內容

  • 姓名:屈彥維 學號:16020610026 轉載自:http://lw.3edu.net/qrs/lw_18446...
    懷光_ee48閱讀 2,693評論 0 2
  • 必備的理論基礎 1.操作系統(tǒng)作用: 隱藏丑陋復雜的硬件接口志秃,提供良好的抽象接口。 管理調度進程嚼酝,并將多個進程對硬件...
    drfung閱讀 3,548評論 0 5
  • Swift1> Swift和OC的區(qū)別1.1> Swift沒有地址/指針的概念1.2> 泛型1.3> 類型嚴謹 對...
    cosWriter閱讀 11,113評論 1 32
  • 別人的總結不一定適合自己浮还,所以盡量多做一些自己的總結,針對自己的薄弱點重點說明闽巩,適當的借鑒別人钧舌,少走一些彎路。最重...
    renkuo閱讀 7,420評論 2 48
  • 那種對于"在路上"的渴望大概從小就在我的腦袋瓜里生著根涎跨,最興奮的事就是坐長途火車到父親單位過暑假洼冻,就是正在鐵路建設...
    沒心情就吃東西閱讀 119評論 0 0