【框架】一種通知到多執行緒框架
阿新 • • 發佈:2021-08-30
目錄
。
前言
本文記錄通過回撥函式通知到多執行緒的框架。
本文連結:李柱明部落格-框架:https://www.cnblogs.com/lizhuming/p/15205560.html
主要用於解耦。
實現原理
就是把多個回撥函式插入到一個連結串列中,在對應的地方執行這個連結串列中的所有回撥函式。
用途
通知業務只是該原理的作用之一,更多用途由使用者自由發揮。
用途之一的通知:各個業務組建一個回撥函式,其內容主要是傳送訊息或其它 IPC。把業務通知到對應執行緒去執行。
也可以點到點通知,底層功能通過 ID 區分業務,找到該業務繫結在該功能的回撥函式執行。
通知結構體原始碼
以下結構體可以按需求修改。
struct notifier {
struct notifier *next;
notify_func func;
void *arg;
};
連結串列管理
採用單向連結串列管理同一類回撥函式。
函式型別
可以按需求修改。
typedef void (*notify_func)(void *, int type, int value);
註冊&登出
註冊:建立一個通知結構體作為節點,配置好引數。插入單向連結串列中。
登出:從連結串列中刪除節點,釋放通知結構體。
使用
函式就是 void notify(struct notifier *notif, int type, int val)
呼叫該函式把連結串列 notif
上的回撥函式都執行一遍。
參考原始碼
底層檔案,實現註冊和登出
/** @file lzm_notifier.c * @brief 簡要說明 * @details 詳細說明 * @author lzm * @date 2021-08-21 17:22:18 * @version v1.0 * @copyright Copyright By lizhuming, All Rights Reserved * @blog https://www.cnblogs.com/lizhuming/ * ********************************************************** * @LOG 修改日誌: ********************************************************** */ #include <stdio.h> #include "lzm_notifier.h" /** * @name add_notifier * @brief add a new function to be called when something happens. * @param * @retval * @author lzm */ int add_notifier(struct notifier **notif, notify_func func, void *arg) { struct notifier *np; for (np = *notif; np != 0; np = np->next) { if (np->func == func && np->arg == arg) { return 0; // already exist } } np = (struct notifier *)os_malloc(sizeof(struct notifier)); if (np == NULL) { os_printf("no mem\n"); return -1; } np->next = *notif; np->func = func; np->arg = arg; *notif = np; return 0; } /** * @name add_notifier * @brief remove a function from the list of things to be called when something happens. * @param * @retval * @author lzm */ void remove_notifier(struct notifier **notif, notify_func func, void *arg) { struct notifier *np; for (; (np = *notif) != 0; notif = &np->next) { if (np->func == func && np->arg == arg) { *notif = np->next; os_free(np); break; } } } /** * @name notify * @brief call a set of functions registered with add_notify. (執行該單向連結串列中的所有回撥函式) * @param * @retval * @author lzm */ void notify(struct notifier *notif, int type, int val) { struct notifier *np; while ((np = notif) != 0) { notif = np->next; (*np->func)(np->arg, type, val); } } /* demo 放到其它檔案 */ struct notifier *lzm_evt_notifer = NULL; /** * @name lzm_register_notifier * @brief * @param * @retval * @author lzm */ int lzm_register_notifier(notify_func func, void *arg) { return lzm_add_notifier(&lzm_evt_notifer, func, arg); } /** * @name lzm_remove_notifier * @brief api * @param * @retval * @author lzm */ void lzm_remove_notifier(notify_func func, void *arg) { remove_notifier(&lzm_evt_notifer, func, arg); } /** * @name lzm_notify * @brief api * @param * @retval * @author lzm */ void lzm_notify(int type, int val) { notify(&lzm_evt_notifer, type, val); }
介面檔案
/** @file lzm_notifier.h
* @brief 簡要說明
* @details 詳細說明
* @author lzm
* @date 2021-08-21 17:33:06
* @version v1.0
* @copyright Copyright By lizhuming, All Rights Reserved
* @blog https://www.cnblogs.com/lizhuming/
*
**********************************************************
* @LOG 修改日誌:
**********************************************************
*/
#ifndef __lzm_notifier_h__
#define __lzm_notifier_h__
typedef void (*notify_func)(void *, int type, int value);
struct notifier
{
struct notifier *next;
notify_func func;
void *arg;
};
extern struct notifier *lzm_evt_notifer;
int add_notifier(struct notifier **notif, notify_func func, void *arg);
void remove_notifier(struct notifier **notif, notify_func func, void *arg);
void notify(struct notifier *notif, int type, int val);
/* demo 放到其它檔案 */
int lzm_register_notifier(notify_func func, void *arg);
void lzm_remove_notifier(notify_func func, void *arg);
void lzm_notify(int type, int val);
#endif /* Head define end*/