C言語を使って様々な組み込み機器を制御するための小さなライブラリを作っています。各デバイスとの通信に UDP ソケットを使用しています。デバイスは、さまざまな興味深いデータ、アラーム、および通知を私に送信すると同時に、ライブラリによって内部的に使用されているが、ユーザーにとって興味深いものではない可能性のあるデータを送信します。そのため、コールバック アプローチを実装しました。ユーザーは、各デバイスでいくつかの興味深いイベントを使用してコールバック関数を登録できます。現在、このライブラリの全体的な設計は次のようになっています:-
- 私は2つのスレッドを実行しています。
- スレッドの 1 つに、各デバイスとの通信を維持するために使用する無限イベントループがあります
while
。select
non-blocking sockets
- 基本的に、デバイスのいずれかからパケットを受信するたびに、20 バイトの役に立たない情報であるヘッダーを取り除き、(そのパケットを取得するために要求が送信された時刻と (パケットが実際に到着した時刻) を含む独自のヘッダーを追加
DEVICE_ID
しREQUES_TIME
ますRETRIEVAL_TIME
。 ) およびREQUEST_ID
(REQUEST_TYPE
アラーム、データ、通知など)。 - ここで、このスレッド (無限ループを持つスレッド) は、新しいヘッダーを持つパケットをリング バッファーに入れ、他のスレッド (スレッド #2) にこの情報を解析するよう通知します。
- スレッド #2 では、通知を受信すると、バッファをロックし、パケットを読み取りポップして解析を開始します。
- すべてのメッセージには、ユーザーが興味を持たない可能性のある情報が含まれているため、ユーザーにとって有用なデータに基づいて行動するためのユーザー コールバック アプローチを提供しています。
基本的に、私はスレッド2でこのようなことをしています:-
スレッド #2
wait(data_put_in_buffer_cond)
lock(buffer_mutex)
packet_t* packet = pop_packet_from_buffer(buf);
unlock(buffer_mutex)
/* parsing the package... */
parsed_packet_t* parsed_packet = parse_and_change_endianess(packet->data);
/* header for put by thread #1 with host byte order only not parsing necessary */
header_t* header = get_header(packet);
/* thread 1 sets free callback for kind of packet it puts in buffer
* This not a critical section section of buffer, so fine without locks
*/
buffer.free_callback(packet);
foreach attribute in parsed_packet->attribute_list {
register_info_t* rinfo = USER_REGISTRED_EVENT_TABLE[header->device_id][attribute.attr_id];
/*user is register with this attribute ID on this device ID */
if(rinfo != NULL) {
rinof->callback(packet);
}
// Do some other stuff with this attribute..
}
free(parsed_packet);
さて、私の懸念は、ユーザーが実装するコールバック関数が完了するまでに時間がかかり、その間にリング バッファーが上書きモードになっているために一部のパケットをドロップする可能性がある場合にどうなるかということです。3 ~ 4 台のデバイスで API をテストしましたが、コールバック関数が適切な時間待機する場合、ドロップ イベントはあまり見られません。このアプローチは最適ではない可能性があると推測しています。
ある種のスレッドプールを使用してユーザーのコールバック関数を実行すると、より良い設計になりますか? その場合、ユーザーのコールバックに送信する前に、パケットの明示的なコピーを作成する必要がありますか? 各パケットは約 500 ~ 700 バイトで、各デバイスから 1 秒あたり約 2 パケットを取得します。現在の設計の改善またはこの問題の解決に関する提案やコメントをいただければ幸いです。