前言
本文记录通过回调函数通知到多线程的框架。
本文链接:李柱明博客-框架: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*/