【框架】一种通知到多线程框架

前言

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