簡體   English   中英

C語言中面向回調的庫的建議

[英]Suggestion for callbacks oriented library in C

我正在使用C語言控制各種嵌入式設備的小型庫。 我正在使用UDP套接字與每個設備進行通信。 設備向我發送各種有趣的數據,警報和通知,同時它們發送一些由庫內部使用的數據,但可能對用戶不感興趣。 所以,我實現了一種回調方法,用戶可以在每個設備上注冊回調函數和一些有趣的事件。 現在,這個庫的整體設計是這樣的: -

  • 我有兩個線程在運行。
  • 在其中一個線程中,有一個無限while事件循環,它使用selectnon-blocking sockets來維護與每個設備的通信。
  • 基本上,每次我從任何設備收到一個數據包時,我都會刪除20個字節的一些無用信息的標頭,並添加我自己的包含DEVICE_IDREQUES_TIME的標頭(發送時間請求以檢索該數據包和RETRIEVAL_TIME (現在是時候了)數據包實際到達)和REQUEST_IDREQUEST_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個字節,每個設備每秒大約可以獲得2個數據包。 任何有關改進當前設計或解決此問題的建議或意見將不勝感激。

每台設備獲得500-700字節根本不是問題,特別是如果您只有3-4台設備。 即使你有100個設備,也不應該是一個問題。 復制開銷很可能是微不足道的。 所以,我的建議是:在你確定緩沖區復制是你的瓶頸之前,不要先嘗試優化。

關於丟失數據包,正如你在問題中所說的那樣,你已經在使用緩沖環(我認為它就像一個循環隊列,對吧?)。 如果隊列已滿,那么您只需要使線程#1等待,直到隊列中有可用空間為止。 顯然,來自不同設備的更多事件可能會到來,但這應該不是問題。 一旦您再次擁有空間, select會告訴您有來自不同設備的可用數據,因此您只需要處理所有數據。 當然,為了擁有一個平衡的系統,您可以將隊列的大小設置為盡可能減少隊列已滿的次數的值,因此,線程#1需要等待。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM