【框架】一種通知到多執行緒框架
- 2021 年 8 月 30 日
- 筆記
- 演算法, 數據結構, C語言, /label/RTOS, /label/lzm, /label/dataStructure, 程式框架, /label/frame, /labbel/C, 源碼集合
前言
本文記錄通過回調函數通知到多執行緒的框架。
本文鏈接:李柱明部落格-框架://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 //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 //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*/

