ロシアの1぀のRTOSの抂芁、パヌト7。タスク間でデヌタを亀換する手段

盞互ロックのレベルでの盞互䜜甚に加えお、タスクは盞互に、およびデヌタレベルで盞互䜜甚する必芁がありたす。 同時に、MAXシステムの際立った特城は、同じコントロヌラヌ内でデヌタを亀換できるだけでなく、





図 1. 1぀のコントロヌラヌ内でのタスクの盞互䜜甚の䟋



コントロヌラヌ間でも、トランスポヌト局を完党に隠したす。





図 2.コントロヌラヌ間のタスクの盞互䜜甚の䟋



さらに、メモリが完党に分離されおいるため、異なるコントロヌラは異なるプロセスず同等です。 圓瀟のりェブサむトで公開されおいるOSバヌゞョンでは、コントロヌラヌ間の物理チャンネルは、有線SPIたたはUARTむンタヌフェヌス、およびRF24無線モゞュヌルを介したワむダレスむンタヌフェヌスにするこずができたす。



SPIおよびUARTオプションを䜿甚するこずは掚奚されたせん。珟圚の実装では、それらを介しお接続できるコントロヌラは2぀たでです。



さらにこれに぀いおさらに説明したす。「知識の本」の他の章はここにありたす。



パヌト1.䞀般情報

パヌト2. RTOS MAXのカヌネル

パヌト3.最も単玔なプログラムの構造

パヌト4.有甚な理論

パヌト5.最初のアプリケヌション

パヌト6.スレッド同期ツヌル

パヌト7.タスク間でデヌタを亀換する手段この蚘事

パヌト8.割り蟌みの凊理



1぀のコントロヌラヌ内でデヌタを亀換する手段メッセヌゞキュヌ



RTOSの操䜜に察する叀兞的なアプロヌチは次のずおりです。タスクはメッセヌゞキュヌを䜿甚しお盞互にデヌタを亀換したす。 少なくずも、それはすべおの孊術教科曞が芁求するものです。 私は実甚的なプログラマヌに属しおいるため、特定のケヌスのために䜜成された盎接的な亀換手段を䜿甚する方が簡単な堎合があるこずを認めおいたす。 たずえば、システムに関連付けられおいない通垞のリングバッファ。 しかし、それでも、メッセヌゞキュヌが最適なオブゞェクトである堎合がありたすシステム以倖のものずは異なり、ポヌリングされるバッファがいっぱいたたは空のずきにタスクをブロックできるためです。



教科曞の䟋を考えおみたしょう。 シリアルポヌトがありたす。 もちろん、回路によっお、システムを簡玠化するために、フロヌ制埡ラむンなしで䜜られおいたす。 ワむダ䞊のデヌタは次々に送られたす。 同時に、倚くのすべおではありたせんが暙準コントロヌラヌの機噚は、倧きなハヌドりェアキュヌを意味したせん。 デヌタを収集する時間がない堎合は、受信シフトレゞスタからの新しい郚分でデヌタが消去されたす。



䞀方、デヌタを凊理するタスクに時間がかかるずしたしょうたずえば、䜜業ツヌルを移動するなど。 これは非垞に正垞です-CNCマシンのGコヌドには䞀定のリヌドがありたす。 ツヌルが移動し、同時に次の線がワむダを通りたす。



コントロヌラのバッファレゞスタがオヌバヌフロヌせず、プログラム内のバむトがメむン操䜜䞭に受信される時間があるため、割り蟌みハンドラで受信する必芁がありたす。 生のバむトがメむンタスクに転送される堎合、最も簡単なオプションが可胜です。





図3



ただし、この堎合、キュヌの配眮ず取り出しの操䜜が倚すぎるこずがわかりたす。 オヌバヌヘッドが高すぎたす。 生のバむトではなく、前凊理の結果をキュヌに入れるこずをお勧めしたす行から開始し、Gコヌドでこの䟋の行を解釈した結果で終了したす。 ただし、割り蟌みハンドラヌでの前凊理は受け入れられたせん 。その時点で、優先床蚭定に応じお他のすべおの割り蟌みがブロックされ、他のサブシステムのデヌタが遅延しお凊理され、補品の動䜜が䞭断されるこずがあるためです。



この仮定はそれを数回繰り返す䟡倀がありたす。 あるフォヌラムで、「PDM圢匏のマむクサりンド甚に暙準のアンパッカヌを䜿甚したしたが、正垞に機胜したせん」ずいう質問を芋たした。 たた、質問に䟋が添付され、PDMフィルタリングが割り蟌みのコンテキストで実行されたした。 質問の䜜成者が䞭断せずにPDMからPCMに倉換し始めたずき圌がすぐにアドバむスされたように、すべおの問題が自然に消えたこずは蚀うたでもない。 したがっお、 䞭断時には、前凊理は受け入れられたせん 電子レンゞで卵を調理したり、割り蟌みハンドラヌで䞍芁なアクションを実行したりしないでください 



前凊理がある堎合、すべおの教科曞で掚奚されるスキヌムは次のずおりです。





図4

高優先床の前凊理タスクは、ほずんど垞にブロックされたす。 割り蟌みハンドラがハヌドりェアからバむトを受信し、プリプロセッサが起動しおこのバむトを枡し、その埌に去りたした。 これ以降、すべおの割り蟌みが再び有効になりたす。



高優先床のプリプロセッサが起動し、内郚バッファにデヌタを蓄積しおからスリヌプ状態になり、再び通垞の優先床でタスクを凊理する機䌚が䞎えられたす。 行が蓄積されるず改行文字が到着したす、それを解釈し、結果をメッセヌゞキュヌに入れたす。 これはすべおの孊術出版物が掚奚するオプションなので、ここで読者に叀兞的なアむデアを䌝える必芁がありたした。 ただし、理論家ずしおではなく、実践者ずしお私自身をすぐに远加したす。この方法の匱点がわかりたす。 キュヌぞのたれな呌び出しで勝ちたすが、優先床の高いタスクに入るためのコンテキストスむッチで負けたす。 䞀般に、このアプロヌチの欠点に぀いお説明されおいたすが、実際の䜜業方法に぀いおは掚奚事項が説明されおいたす。パフォヌマンスずシンプルさの最適な比率を遞択しお、誰もが独自の方法を芋぀ける必芁がありたす。 実際の芋積もりを䌎ういく぀かの掚奚事項は、䞭断に関する次の蚘事に蚘茉されたす。



メッセヌゞキュヌを実装するには、MessageQueueクラスを䜿甚したす。 メッセヌゞキュヌは任意のタむプのデヌタで効果的に機胜する必芁があるため、テンプレヌトずしお蚭蚈されおいたす匕数ずしおデヌタタむプが眮き換えられたす。



template <typename T> class MessageQueue { ...
      
      





コンストラクタヌの圢匏は次のずおりです。



MessageQueuesize_t max_size;



max_sizeパラメヌタヌは、キュヌの最倧サむズを決定したす。 容量がいっぱいになったずきに芁玠をキュヌに入れようずするず、空きスペヌスができるたでタスクがブロックされたす䞀郚のタスクは、既にキュヌにある芁玠の1぀を䜿甚したせん。



あたりにも倚くのこずがすでに述べられおいるので、ここではキュヌの初期化の䟋をせずにはできたせん。 キュヌ芁玠のタむプがshortであり、キュヌの次元が5芁玠を超えないこずが明らかなテストフラグメントを取埗したす。



 voidMessageQueueTestApp::Initialize() { mQueue = new MessageQueue<short>(5); Task::Add(new MessageSenderTask("send"), Task::PriorityNormal, 0x50); Task::Add(new MessageReceiverTask("receive"), Task::PriorityNormal, 0x50); }
      
      





関数を䜿甚しおメッセヌゞをキュヌに入れるこずができたす



結果プッシュ定数Tおよびメッセヌゞ、uint32_t timeout_ms = INFINITE_TIMEOUT;



キュヌがいっぱいの堎合、timeout_msパラメヌタヌが必芁です。 この堎合、システムは空き領域が衚瀺される瞬間を埅ちたす。 そしお、このパラメヌタヌ-埅機が蚱可される量を䌝えたす。



必芁に応じお、メッセヌゞをキュヌの最埌ではなく、最初に眮くこずができたす。 これを行うには、次の関数を䜿甚したす。



結果PushFrontconst Tメッセヌゞ、uint32_t timeout_ms = INFINITE_TIMEOUT;



キュヌの先頭から次の芁玠を削陀するには、次の関数を䜿甚したす。



結果ポップTメッセヌゞ、uint32_t timeout_ms = INFINITE_TIMEOUT;



ここで、それぞれタむムアりトパラメヌタは、キュヌが空の堎合の埅機時間を蚭定したす。 蚭定された時間の間、システムは、他のタスクによっおキュヌに入れられたメッセヌゞが衚瀺されるのを埅ちたす。



芁玠を削陀せずに、キュヌの先頭から芁玠の倀を取埗するこずもできたす。



結果のピヌクTメッセヌゞ、uint32_t timeout_ms = INFINITE_TIMEOUT;



最埌に、キュヌに入っおいるメッセヌゞの数を調べる関数がありたす。



size_tカりント



および可胜な最倧キュヌサむズ



size_t GetMaxSize



異なるコントロヌラヌ間の通信手段



実際、玔粋に圢匏的には、コントロヌラヌ間でデヌタを亀換する手段はドラむバヌです。 しかし、むデオロギヌ的に、それらはデヌタ亀換の通垞の手段に関連しおいたす。これはMaxの䞻な機胜の1぀です。



OSの公開バヌゞョンでは、有線UARTたたはSPIむンタヌフェヌス、たたはRF24無線モゞュヌルSPIむンタヌフェヌスに接続されおいるを介しお物理的な亀換を実行できるこずを思い出しおください。 たた、コントロヌラヌ間のデヌタ亀換をアクティブにするには、MaksConfig.hファむルに次の行を入力する必芁があるこずを思い出しおください。



#define MAKS_USE_SHARED_MEM 1



定数の1぀を1に蚭定しお、物理チャネルのタむプを決定したす。



MAKS_SHARED_MEM_SPI、MAKS_SHARED_MEM_UART、たたはMAKS_SHARED_MEM_RADIO



珟圚の実装のSPIおよびUARTメカニズムは2぀のデバむスのみの接続を提䟛するため、無線オプションが掚奚されたす



さお、このような長匕いた前文の埌、SharedMemoryクラスの調査を始めたしょう。

クラスオブゞェクトは、Initialize関数を䜿甚しお初期化できたす。 「猶」ずいう蚀葉は偶然䜿甚されたせん。 䞀般に、ラゞオオプションの堎合、初期化は必芁ありたせん。



デヌタ構造はこの関数に枡されたす。 そのフィヌルドに぀いお簡単に考えおみたしょう。







この構造䜓を埋めお初期化関数を呌び出す䟋を怜蚎しおください。



  SmInitInfo info; info.TransferCore = &SpiTransferCore::GetInstance(); info.NotifyMessageReceived = true; info.AutoSendContextsActivity = true; info.SendActivityDelayMs = 100; info.CheckActivityDelayMs = 200; SpiTransferCore::GetInstance().Initialize(); SharedMemory::GetInstance().Initialize(info);
      
      





別のオプション



  SmInitInfo info; info.TransferCore = &SpiTransferCore::GetInstance(); info.AutoSendContextsActivity = true; info.SendActivityDelayMs = 100; info.CheckActivityDelayMs = 200; SpiTransferCore::GetInstance().Initialize(); SharedMemory::GetInstance().Initialize(info);
      
      





このクラスは、タスクの盞互䜜甚のための2぀のメカニズム-メッセヌゞず共有メモリブロッキングの可胜性ありを提䟛したす。



共有メモリオブゞェクトは垞に1぀であるため、オペレヌティングシステムの開発者は、耇雑な関数名をグロヌバルな名前に倉換するMaksSharedMemoryExtensions.cppファむルを䜜成したした。



このファむルのスニペットは次のずおりです。



 Result GetContext(uint32_t context_id, void* data) { return SharedMemory::GetInstance().GetContext(context_id, data); } Result GetContext(uint32_t context_id, void* data, size_t data_length) { return SharedMemory::GetInstance().GetContext(context_id, data, data_length); } Result SetContext(uint32_t context_id, const void* data, size_t data_length) { return SharedMemory::GetInstance().SetContext(context_id, data, data_length); }
      
      





配信パッケヌゞに含たれるすべおのアプリケヌションはグロヌバル関数名を䜿甚するため、このドキュメントの䟋ではこの呜名オプションも䜿甚したす。



メッセヌゞ



投皿から始めたしょう。 それらを送信するには、SendMessage関数を䜿甚したす。 この関数は非垞に耇雑なので、詳现に怜蚎しおください。



結果SendMessageuint32_t message_id、const void * data、size_t data_length



匕数



message_id-メッセヌゞ識別子。

data-メッセヌゞデヌタぞのポむンタヌ。

data_length-メッセヌゞデヌタの長さ。



䜿甚䟋



  const uint32_t APP5_EXPOSE_MESSAGE_ID = 503; ... if (broadcast) { char t = 0; SendMessage(APP5_EXPOSE_MESSAGE_ID, &t, sizeof(t)); } const uint32_t APP5_AIRPLANE_MESSAGE_ID = 504; ... bool AirplaneTask::SendAirplane() { Message msg(_x, _y, _deg, _visibility); return SendMessage(APP5_AIRPLANE_MESSAGE_ID, &msg, sizeof(msg)) == ResultOk; }
      
      





関数の結果は、メッセヌゞの送信ステヌタスを反映しおいたす。 受信者が受信したかどうかにかかわらず、この機胜はサむレントです。 それがなくなったかどうかだけが知られおいたす。 確認するには、受信者が返信メッセヌゞを送信する必芁がありたす。



したがっお、受信者偎でメッセヌゞを埅機するには、次の関数が䜿甚されたす。



結果WaitUntilMessageReceivedSmMessageReceiveArgsargs、uint32_t timeout_ms = INFINITE_TIMEOUT



匕数



args-メッセヌゞパラメヌタを持぀オブゞェクトぞのリンク。



timeout_ms-ミリ秒単䜍のタむムアりト。 タむムアりト倀がINFINITE_TIMEOUTの堎合、タスクはタむムアりトによるロック解陀の可胜性なしでブロックされたす無限埅機。



メッセヌゞオプションはクラス党䜓です。 オヌプンメンバヌを簡単に怜蚎しおください。



uint32_t GetMessageId

受信したメッセヌゞの識別子を返したす



size_t GetDataLength

受信したメッセヌゞのデヌタサむズをバむト単䜍で返したす。



void CopyDataTovoid *タヌゲット

メッセヌゞデヌタを指定されたバッファにコピヌしたす。 バッファのメモリは事前に割り圓おる必芁がありたす。 バッファヌのサむズは、メッセヌゞデヌタGetDataLengthメ゜ッドを呌び出した結果のサむズ以䞊でなければなりたせん。



したがっお、前の䟋で送信されたメッセヌゞの受信に圹立぀䟋は次のようになりたす。



  void MessageReceiveTask::Execute() { Message msg; while (true) { SmMessageReceiveArgs args; Result res = WaitUntilMessageReceived(args); if (res == ResultOk) { uint32_t mid = args.GetMessageId(); switch (mid) { .... case APP5_EXPOSE_MESSAGE_ID: #ifdef BOARD_LEFT _gfx->ExposeAirplaneRed(); #else _gfx->ExposeAirplaneBlue(); #endif break; case APP5_AIRPLANE_MESSAGE_ID: { args.CopyDataTo(&msg); #ifdef BOARD_LEFT _gfx->UpdateAirplaneRed(msg.X, msg.Y, msg.Deg); _gfx->SetAirplaneRedVisibility(msg.Visibility); #else _gfx->UpdateAirplaneBlue(msg.X, msg.Y, msg.Deg); _gfx->SetAirplaneBlueVisibility(msg.Visibility); #endif } break; ...
      
      





同期されたコンテキスト



コンテキストは、すべおのコントロヌラヌ間で同期する必芁があるメモリの領域を指したす。 同期䞭に远求される目暙は任意です。 最も単玔なケヌスは、1぀のデバむスがホットスタンバむの完了した䜜業段階に぀いお他のデバむスに通知するこずです。 倱敗した堎合、残りのデバむスには䜜業をピックアップする方法に関する情報がありたす。 䞀緒に目暙を達成するデバむスの堎合、コンテキストを介した亀換のメカニズムは、メッセヌゞを介したものよりも䟿利かもしれたせん。 メッセヌゞを生成、送信、受信、デコヌドする必芁がありたす。 たた、コンテキストのメモリを䜿甚するず、通垞のメモリず同じように䜜業できたす。1぀のデバむスのメモリが他のデバむスに耇補されるように、同期を忘れないこずが重芁です。



システム内の同期されたコンテキストの数は任意です。 したがっお、すべおを1぀に収める必芁はありたせん。 さたざたなニヌズに合わせお、さたざたな同期コンテキストを䜜成できたす。 メモリのサむズ、その䞭のデヌタ構造、および同期されたコンテキストの他のパラメヌタヌは、アプリケヌションプログラマの関心事ですそれ自䜓、同期されたメモリの量が倚いほど、同期が遅くなりたす。そのため、異なるニヌズに察しお異なる小さなコンテキストを䜿甚する方が良いです。



さらに、同期セッションの瞬間でさえ-アプリケヌションプログラマによっお遞択されたす。 RTOS MAXはサポヌト甚のAPIを提䟛したすが、アプリケヌションプログラマはその関数を呌び出す必芁がありたす。 これは、デヌタ亀換のプロセスが比范的遅いずいう事実によるものです。 すべおがオペレヌティングシステムに巊右される堎合、プロセッサコアが他のタスクを最倧化する必芁があるずきに遅延が発生する可胜性がありたす。 コンテキストを頻繁に自動同期するず、リ゜ヌスが無駄になりたす。たれに、コントロヌラヌが同期する前にデヌタが叀くなる可胜性がありたす。 これには、デヌタがより重芁な質問たずえば、4人の異なるサブスクラむバヌがある堎合を远加したす。その埌、アプリケヌションプログラマヌのみが同期を開始できるこずが完党に明らかになりたす。 これを行うのが最適なタむミングを知っおいるのは圌であり、どのサブスクラむバヌが残りのデヌタを他のサブスクラむバヌに配垃すべきかを知っおいたす。 䞀方、OSはアプリケヌションに透過性を提䟛したす。



コンテキストには、独自の数倀識別子がありたすアプリケヌションプログラマによっお蚭定されたす。 すべおのアプリケヌションは、1぀たたは耇数の同期されたコンテキストを持぀こずができたす。 盞互に䜜甚するコントロヌラヌ内で識別子が䞀貫しおいるこずが重芁です。

同期デヌタの最も単玔な䟋-枅掃ロボットは、枅掃されおいない領域を把握するために、枅掃した領域を定期的に地図䞊にマヌクしたす。たた、お互いに干枉しないように、今どこに行くのかを知らせたす。 1぀の補品で䜜業しおいるレンチは、ねじ蟌みが完了した埌、各ねじナットにマヌクを付けたす。 タッチスクリヌン付きのボヌドはクリックを蚘録し、残りのボヌドに぀いおこの事実を蚘録したした。 さお、メモリを共有する必芁がある他の倚くのケヌスがありたすが、これを毎秒数回最倧-毎秒数十回行うこずが蚱可されおいたす。



したがっお、コンテキストは図に瀺すように衚すこずができたす。





図 5.コンテキスト



そしお、その目的は次の図で衚すこずができたす。





図 6.コンテキスト同期の本質



次に、コンテキストの同期に䜿甚される関数を怜蚎したす。



結果GetContextuint32_t context_id、void * data;



コンテキストデヌタを指定されたメモリ領域にコピヌしたす。メモリは事前に割り圓おられおいる必芁がありたす。 デヌタ長が事前にわかっおいる堎合䟋えば、単玔なフィヌルドを持぀構造に適しおいたす。



匕数



context_id-コンテキスト識別子。



data-コンテキストを保存するためのポむンタメモリ領域。



その結果、最埌の同期䞭に取埗された、指定された識別子を持぀コンテキストデヌタが返されたす。 したがっお、デヌタはコンテキストのロヌカルコピヌから取埗されるため、この関数はすばやく動䜜したす。 この関数には2番目のバリアントがありたす。



結果GetContextuint32_tcontext_id、void *data、size_tdata_length;



メモリを割り圓お、デヌタずコンテキストの長さをコピヌしたす。 デヌタ長が事前にわからない堎合たずえば、任意の長さの配列に適しおいたす。



匕数



context_id-コンテキスト識別子。



data-コンテキストを保存するためのポむンタメモリ領域。



data_length-コンテキストを栌玍するメモリ領域のバむト単䜍のサむズ。



原則ずしお、コンテキストが曎新されるのを埅぀タスクを䜜成しおから、その新しいデヌタをアプリケヌションメモリにコピヌできたす。 これには次の関数が適しおいたす。



結果WaitUntilContextUpdateduint32_tcontext_id、uint32_t timeout_ms = INFINITE_TIMEOUT



匕数



context_id-コンテキスト識別子。



timeout_ms-ミリ秒単䜍のタむムアりト。 タむムアりト倀がINFINITE_TIMEOUTの堎合、タスクはタむムアりトによるロック解陀の可胜性なしでブロックされたす無限埅機。



最埌に、タスクがシステム党䜓耇数のコントロヌラヌで構成されるでコンテキストを曎新したい堎合を考えたす。



最初に、コンテキストをキャプチャする必芁がありたす。 これを行うには、次の関数を䜿甚したす。



結果LockContextuint32_t context_id



匕数



context_id-コンテキスト識別子。



この機胜にはコントロヌラヌ間の亀換が必芁であるため、時間がかかる可胜性がありたす



コンテキストがキャプチャできた堎合同時にキャプチャしようずするず、1぀だけが勝ち、残りぱラヌコヌドを受け取りたす、次の関数を䜿甚しおコンテキストを蚘述できたす。



結果SetContextuint32_t context_id、const void * data、size_t data_length



匕数



context_id-コンテキスト識別子。



data-コンテキストを保存するためのメモリ領域ぞのポむンタ。



data_length-コンテキストを栌玍するメモリ領域のバむト単䜍のサむズ。



最埌に、コンテキストを同期するには、関数を呌び出す必芁がありたす。



結果UnlockContextuint32_t context_id



匕数



context_id-コンテキスト識別子。



コンテキストがシステム党䜓で同期するのは、呌び出し埌です。



この機胜にはコントロヌラヌ間の亀換が必芁であるため、時間がかかる可胜性がありたす



䜜業䟋



OSに付属する同期コンテキストを䜿甚した実際の䟋を考えおみたしょう。 コヌドはファむルに含たれおいたす... \ maksRTOS \ Source \ Applications \ CounterApp.cpp



この䟋では、耇数のデバむスが1秒に1回カりンタヌをむンクリメントしたすこのアプリケヌションを画面のあるボヌドで実行するず、カりンタヌ倀が芖芚的に衚瀺されたす。 コントロヌラヌのいずれかがオフになっおからオンになった堎合、カりンタヌの珟圚の内容を受け取り、すべおのナヌザヌず連携しお動䜜したす。 したがっお、システムは、少なくずも1぀のコントロヌラヌがそのシステム内で動䜜するたでカりントを続けたす。



この䟋を実行したアプリケヌションプログラマは、「なぜですか」ずいう原則に基づいおコンテキスト識別子を遞択したした。



 static const uint32_t m_context_id = 42;
      
      





同期されるメモリは単玔に芋えたす



  uint32_t m_counter;
      
      





関心のある䞻なアクションは、関数で発生したす。



void CounterTask ::実行



最初に、コントロヌラヌは芋぀けようずしたすシステムの最初ではありたせんか これを行うために、圌はコンテキストを取埗しようずしたす



  Result result = GetContext(m_context_id, & m_counter);
      
      





コントロヌラヌが最初ではない堎合、コンテキストが受信され、途䞭でシステムに存圚するカりンタヌ倀が受信されたす。



コントロヌラが最初の堎合、コンテキストは受信されたせん。 この堎合、次のように䜜成する必芁がありたす同じ堎所で、カりンタヌは途䞭で消えたす。



  if ( result != ResultOk ) { m_counter = 0; result = LockContext(m_context_id); if ( result == ResultOk ) { SetContext(m_context_id, & m_counter, sizeof(m_counter)); UnlockContext(m_context_id); } }
      
      





すべおが、今では確実にコンテキストが存圚し、接続したばかりのシステムで発芋されたか、䜜成されたした。 無限ルヌプに入りたす



  while (true) {
      
      





そこで1秒間埅機したす。



  Delay(MAKS_TICK_RATE_HZ);
      
      





そしお、システム党䜓にカりンタヌを配垃する暩利をめぐっおコンテストに勝ずうずしおいたす。



  result = LockContext(m_context_id);
      
      





成功したら、配垃したす



  if ( result == ResultOk ) { GetContext(m_context_id, & m_counter); ++ m_counter; SetContext(m_context_id, & m_counter, sizeof(m_counter)); UnlockContext(m_context_id); }
      
      





どうやら、コンテキストを配垃したすが、受け取りたせん。 実際、この䟋では、新しく接続されたデバむスのみがコンテキストを取埗したす。 受信した堎合、デバむスは自埋的に動䜜したす。 もちろん、絶えず連絡を取り合う方が良いですが、そのようなシステムの説明はより倚くの玙を取りたす、そしおあなたは心理孊に反察するこずはありたせん、ほずんどの読者は単にあくびしお次のセクションに進みたす。 共有メモリの原理は、倚かれ少なかれ明確になったず思いたす。



All Articles