QNXオペレーティングシステムの情報転送-qnxタスク間のメッセージ転送情報の転送

転載:https//blog.csdn.net/xjhhjx/article/details/77139457

1.
QNXメッセージの概要QNXメッセージは、同期メッセージと非同期メッセージに分けることができます。非同期(パルス)メッセージは主に通知メカニズムを反映しますが、同期メッセージは主に、メッセージ配信のプロセスで両方の当事者が互いに協力する必要があるプロセスを指します。
2. QNXメッセージ配信のいくつかの基本概念
1.チャネルとリンク
メッセージ配信は、サーバーとクライアントのモデルに基づいています。QNX6は、「チャネル」の概念を抽象化します。チャネルはサービスへの入り口です。チャネルがサービスに提供する必要のあるスレッドの数に関しては、サーバー自体のビジネスです。サーバーに複数のサービスがある場合、サーバーは複数のチャネルを開くこともできます。クライアントは、「チャネル」にメッセージを送信する前に接続(接続)を確立してから、接続でメッセージを送信する必要があります。このようにして、同じクライアントが必要に応じて同じチャネルで複数の接続を確立できます。
2.名前空間(name_space)
クライアントとサーバー間の通信では、クライアントがサーバーのnd / pid / chidを簡単に認識できるように、サーバープロセスはパス名を登録し、それをndに関連付けることができます。 pid、およびサービスチャネルのchid。クライアントは、接続サーバーのパス名を要求するだけで済みます。

QNX同期信号3.クライアントサーバ通信

1.クライアントモデル
接続ID取得するためにサーバ・チャネルに接続する1)コールname_open(PATH)
3)を応答するサーバのメッセージウェイトを送信するコールAPI
4)場合応答を受信したら、name_close()を呼び出して接続

2を閉じます。サーバーモデル
1)name_attachを呼び出して名前を登録し、チャネルを作成します
2)メッセージを受信して​​処理します
3)メッセージ処理結果に応答します
4)name_detachは名前を名前空間から削除します

3、クライアントサーバーメッセージングプロセス
1)サーバー
はクライアントからのネームスペース接続要求を登録します2)クライアントは名前空間に接続されます
3)クライアントはMsgSendインターフェイスを呼び出してサーバーにメッセージを送信し、クライアントはブロッキングを送信します
4)サーバーはMsgReceiveを呼び出しますインターフェイスデータを受信し、クライアントは応答をブロックしています
5)サーバーはメッセージを処理し、MsgReply関数を呼び出して応答メッセージを送信します
6)クライアントはMsgSend関数から戻ってブロックを解除します

4.マルチチャネルメッセージ転送を使用して改善します効率
。iov_tを使用してデータを「収集」します。つまり、一度に複数のデータを転送できます。ヘッダーとdatabufは隣接していない2つのメモリですが、サーバー側のReceiveBufferに渡されると連続します。
SETIOV(&iov [0]、&header、sizeof(header));
SETIOV(&iov [1]、databuf、datalen);
MsgSendvs(ConnectionId、iov、2、Replybf、ReplyLen);

5.メッセージ配信の方向とMsgDeliverEvent( )
クライアントはサーバーにメッセージを送信します。サーバーはすぐに応答できず、クライアントは待機したくありません。この状況での正しいアプローチは、要求が一定期間後に処理され、クライアントが実行を継続できることをクライアントに通知することです。サーバーがタスクを完了すると、サーバーはクライアントに要求を通知する何らかの方法が必要です。完了です。

クライアント:「通知イベント」を準備し、MsgSend()を使用してこのイベントをサーバーに送信します。つまり、「xxxが発生した場合は、このイベントを使用して通知してください」という意味です。
  サーバー:このメッセージを受信した後、その時点でのrcvidと通過したインシデントを記録し、「OK、了解しました」と返信します。 
  クライアント:サーバーからの応答により、クライアントはブロックされなくなり、他のことを実行できます 
  ... 
  サーバー:ある時点で、クライアントから要求された「xxx状況」が満たされ、サーバーはMsgDeliverEvent(rcvid 、event);クライアントクライアントに通知するには 
  :通知を受信した後、MsgSend()を使用して「xxxシチュエーションのデータはどこにありますか?」を送信し 
  ますサーバー:MsgReply()を使用してデータをクライアントに返します

  int MsgDeliverEvent(int rcvid、const struct sigevent * event);
イベントサーバーを変更する必要はありません。rcvidはサーバーによってクライアントから受信されます。サーバーがクライアントに応答するとき、このIDは無意味になります。さらに、MsgDeliverEventは非ブロッキング関数です。

6.一般的な
APIChannelCreate()、ChannelDestroy()
    ConnectAttach()、ConnectDetach()
    MsgDeliverEvent()
    MsgError()
    MsgRead()、MsgReadv()
    MsgReceive()、MsgReceivePulse()、MsgReceivev()
    MsgReply(v)、MsgReply()
    MsgSend()、MsgSendnc()、MsgSendsv()、MsgSendsvnc()、MsgSendv()、 
MsgSendvnc()、MsgSendvs()、MsgSendvsnc()
  MsgWrite()、MsgWritev()

name_close)、name_close)()とname_open()


7 。まとめ
1)クライアントは、サービスにメッセージを送信するときにサーバー応答バッファーを指定します
。2)サーバーは、クライアントがメッセージに応答するときにMsgSend戻り値としてパラメーターを渡します(MsgReply)。3)
サーバーは次の場合にそれを実行できますMsgReceive Passingパラメータは、
クライアントから送信されたメッセージに関する情報を取得するために使用されます4)クライアントがサービスネームスペースを開くと、システムはサーバーに_IO_CONNECTメッセージを送信します
5)クライアントがネームスペースを切断または閉じると、サーバーはそれを受信します_PULSE_CODE_DISCONNECTパルス
6)クライアントビューはサーバーが_PULSE_CODE_UNBLOCKパルス
時間を受信した時間からREPLY BLOCKのブロックを解除します7)名前を作成するために自動的に設定されます_NTO_CHF_DISCONNECT_NTO_CHF_COID_DISCONNECT、システム



通知パルス-DISCONNECT、システムcannotificationパルス
1、基本概念
パルスは実際には短いメッセージのようなもので、「接続」でも送信されます。パルスの最大の特徴は、非同期であるということです。送信者は受信者の応答を待つ必要がなく、直接実行を続けることができます。ただし、この非同期性によってパルスも制限されます。パルスが伝送できるデータの量は限られています。異なるパルスを区別するための8ビットの「コード」フィールドと、データを伝送するための32ビットの「値」フィールドのみがあります。パルスの主な目的は、「通知」(通知)を実行することです。カーネルは、ユーザープログラムだけでなく、特別な「システムパルス」を生成してユーザープログラムに送信し、特別な状況の発生を通知します。

2.パルスを受信するとき
は、チャネル上に他のメッセージがないことを確認してください。パルスしかない場合は、MsgReceivePulse()を使用してパルスのみを受信できます。チャネルがメッセージとパルスの両方を受信できる場合は、MsgReceive()を直接使用します。 、受信バッファ(ReveiveBuf)が少なくとも1つのパルス(sizeof struct _pulse)を保持できることを確認してください。MsgReceive()によって返されるrcvidが0の場合は、パルスが受信されたことを意味します。それ以外の場合は、メッセージが受信されたことを意味します。

3.パルス信号特性
1)40ビットデータ(8ビットパルスコード、32ビットデータ)を効果的に送信
2)送信側はノンブロッキング
3)他のメッセージと同様に受信可能
4)パルスは受信機がパルスの待機をブロックしていない限り、キューに入れられます。
5)パルスがない場合、レシーバーはパルスをブロックして待機し

ます。4。関連するデータ構造とAPI
struct _pulse {       uint16_t type;       uint16_t subtype;       int8_t code;       uint8_t zero [3];




      union sigval value;
      int32_t scoid;
  };
valueは
      unionunion sigval {       int sival_int;       void * sival_ptr;      };  int MsgReceivePulse(int chid、         void *         rmsg、int rbytes、         struct _msg_info * info); V.非同期メッセージ1、一般的に使用される非同期信号asyncmsg_channel_create()asyncmsg_channel_destroy()asyncmsg_connect_attach()asyncmsg_connect_detach()asyncmsg_flush()asyncmsg_put()、asyncmsg_get()asyncmsg_free()async flagmsg_malloc()2、int async_channels unsigned flag


























mode_t mode、
size_t buffer_size、
unsigned max_num_buffer、
const struct sigevent * ev、
int(* recvbuf_callback)(
size_t bufsize、
unsigned num_bufs、
void * bufs []、
int flags、
void * handle)、
void * recvbuf_callback_handle

:description channel );属性、デフォルト設定は_NTO_CHF_ASYNCです。_NTO_CHF_ASYNC_NONBLOCKが設定されている場合、 
asyncmsg_get()を呼び出したときにメッセージが到着しないと、プログラムはブロックしません。

モード:チャネル属性を設定します

Buff_size:メッセージを格納するためのバッファのサイズを設定します

Max_num_buffer:メッセージを格納するためのバッファの最大数を設定します

Ev:NULLまたはsigevent構造へのポインタ。受信このイベントが自動的に

Recvbuf_callback:NULLまたは関数ポインターを送信する場合、受信したメッセージがNULLのときにそれを格納するためのスペースを割り当てるために使用されます

。Mallocrecvbuf_callback_handle:を使用してRecvbuf_callback関数に渡されます。

注:
Recvbuf_callbackがNULLでない場合:
コールバック関数は、asyncmsg_get()が呼び出されるたびにトリガーされ(フラグはASYNCMSG_RECVBUF_ALLOCに設定され、bufsはメッセージを指します...)、他のメッセージを受信する場合は1を返し、0を返すと停止します。
asyncmsg_channel_destroy()を呼び出すと、コールバック関数が複数回トリガーされてスペースが解放され、フラグがASYNCMSG_RECVBUF_FREEに設定されます。


int asyncmsg_channel_destroy(int chid);

chid:チャネルIDの
説明:
Recvbuf_callbackがNULLでない場合、各呼び出しはスペースの解放をトリガーし、デフォルトの呼び出しは解放されます。

戻り値:
成功:EOK
失敗:-1-> errno

int asyncmsg_connect_attach(
uint32_t nd、
pid_t pid、
int chid、
unsigned index、
unsigned flags、 
const struct _asyncmsg_connection_attr * attr);

パラメーターの説明:
Nd / pid / chid:どのコンピューター/プロセスID /チャネルID

インデックス:許容可能な最小の接続ID(開始値)

フラグ:
_NTO_COF_NOSHARE:アプリケーションは独自のBUFFERを使用します。それ以外の場合は、asyncmsg_malloc()を使用し、asyncmsg_put()が呼び出されたときにフィルデータが送信されます。

_NTO_COF_NONBLOCK:送信ヘッダーがビジーの場合、待機をブロックする必要はありません属性

接続属性を指定します
戻り値:
成功:接続IDが
失敗しました:-1

int asyncmsg_connect_detach(int coid);


パラメーター:
coid:接続ID
備考:
指定された接続から切断します、送信側のすべてのメッセージは破棄されます。これより前のすべてのメッセージが送信されている場合は、この前にasyncmsg_flush()インターフェイスを呼び出す必要があります。

戻り値:
成功:EOK
失敗:-1

int asyncmsg_flush(int coid、
int mode);

パラメーターの説明:
Coid:接続ID

モード:
0、この関数をブロックしたくない場合は、ASYNCMSG_FLUSH_NONBLOCKを設定します 

戻り値:
成功:EOK
失敗:-1

int asyncmsg_connect_attr(
int coid、
struct _asyncmsg_connection_attr * old_attr、 
const struct _asyncmsg_connection_attr * new_attr);

パラメーターの説明:
coid:接続ID
Old_attr:現在の属性
new_attr:新しい属性

戻り値:
成功:EOK
失敗:-1


int asyncmsg_put(int coid、
const void * buff、
size_t size、 
unsigned handle)、
int(* call_back)(
int err、
void * buf、
unsigned handle));

int asyncmsg_putv(int coid、
const iov_t * iov、
int parts、 
unsigned handle、
int(* call_back)(
int err、
void * buf、
unsigned handle ));
パラメータの説明:
Coid:接続ID
バフ:メッセージバッファ
サイズ:メッセージサイズ
Iov:IOVメッセージを格納するアレイ
パーツ:IOVアレイサイズ
ハンドル:ユーザー定義データはコールバック関数に渡され、パッケージタイプを区別するために使用され
ますcall_back:NULLまたは関数ポインター。メッセージの配信後に呼び出されます
。NULLの場合、_asyncmsg_connection_attrがasyncmsg_connect_attachに渡されて呼び出されます。


struct _asyncmsg_get_header * asyncmsg_get(int chid);

パラメータの説明:Chid
:チャネルIDの
説明:関数は最大5つの非同期メッセージを受信します。さらにメッセージを受信するには、このインターフェイスを周期的に呼び出す必要があります。NULLが返され、errnoがEAGAINであることを認識しています。読み取りが完了したことを意味します。

戻り値の型:
struct _asyncmsg_get_header { struct _msg_info info; int err; iov_t * iov; int parts; struct _asyncmsg_get_header * next; unsigned reserved [2]; };説明:情報:非同期信号情報構造エラー:エラーステータスIvo:を指すメッセージ本文パーツ:ivo配列サイズ次:次の情報構造体を指す戻り値:成功:情報リンクリスト失敗:NULL




















void asyncmsg_free(void * buf);

パラメータの説明:
buf:メモリを解放するためのポインタ
説明:
 asyncmsg_get()呼び出しにより、メモリが解放され


ますvoid * asyncmsg_malloc(size_t size);

説明:この
関数は、メッセージを送信するためのスペースを割り当てます。

おすすめ

転載: blog.csdn.net/modi000/article/details/113877196