从操作系统内核看设计模式--linux内核的Observer模式

简介:

Linux虽然是面向过程的c语言写成的,但是却可以表达面向对象的思想,这个问题上,“语言是无关紧要的”,既然是一个语言,那么如果它是成功的,那么它就必须可以表达任何含义,因此软件设计思想和语言是无关的,总听见有人说用c语言无法写面向对象的程序,我无语!用c语言不但可以表达OO,而且可以表达任何的设计模式,这里设计模式和OO还有语言没有必然的关系,设计模式是一种大的框架性的理念,而OO是一种实现方式,至于或语言,那是更低层次的实现方式,据个例子,用中文可以写出一句话,如果用日文或者英文写不出同样含义的一句话,那么日文或者英文就是有缺陷的,现实证实它们没有缺陷,只是表达方式不同罢了,同样莎士比亚可以用英文写出名剧,用中文,李白可以写出妙诗,同样都是艺术作品。

linux中的观察者模式是最显然的了,就是“通知链”模型,在linux中,如果你想让自己的行为被别人注意到,那么你就要申请一条通知链,然后让所有关注你自己的实体注册到这条通知链上,最终的效果就是一旦发生一件值得关注的事情,所有的注册者都可以得到通知,想得到通知的实体注册代码如下:

int atomic_notifier_chain_register(struct atomic_notifier_head *nh, struct notifier_block *n)

{

unsigned long flags;

int ret;

spin_lock_irqsave(&nh->lock, flags);

ret = notifier_chain_register(&nh->head, n);

spin_unlock_irqrestore(&nh->lock, flags);

return ret;

}

static int notifier_chain_register(struct notifier_block **nl, struct notifier_block *n)

{

while ((*nl) != NULL) {

if (n->priority > (*nl)->priority)

break;

nl = &((*nl)->next);

}

n->next = *nl;

rcu_assign_pointer(*nl, n);

return 0;

}

以上的代码中atomic_notifier_chain_register的参数nh就是希望别人关注的实体申请的一条通知链,而参数n就是关注的实体注册的一个结构,该结构体包含了一个回调函数,一旦通知来临,该回调函数被调用。c语言中的回调函数其实和OO中的抽象类和接口中的抽象方法的意义是一样的,本质上就是一个接口,只是告诉调用方你只管调用就可以了,不必知道它的实现以及是否已经被实现,也不用管它到底做了哪些事,在观察者模式中,实际上解耦了通知者和被通知者,因此应用观察者模式可以得到两个好处,第一可以轻松实现框架的层次感,做到各司其职,第二就是可以合理安排对所在的层次,一个对象没有必要什么都管,这其实不是两个好处,而是一个好处的两个方面。这样我就可以独立的更改通知者的通知方式和被通知者得到通知的时候的反映方式。对于linux而言,主动通知的代码是以下:

int __kprobes __atomic_notifier_call_chain(struct atomic_notifier_head *nh, unsigned long val, void *v, int nr_to_call, int *nr_calls)

{

int ret;

rcu_read_lock();

ret = notifier_call_chain(&nh->head, val, v, nr_to_call, nr_calls);

rcu_read_unlock();

return ret;

}

static int __kprobes notifier_call_chain(struct notifier_block **nl, unsigned long val, void *v, int nr_to_call, int *nr_calls)

{

int ret = NOTIFY_DONE;

struct notifier_block *nb, *next_nb;

nb = rcu_dereference(*nl);

while (nb && nr_to_call) {

next_nb = rcu_dereference(nb->next);

ret = nb->notifier_call(nb, val, v); //调用观察者注册是回调函数

if (nr_calls)

(*nr_calls)++;

if ((ret & NOTIFY_STOP_MASK) == NOTIFY_STOP_MASK)

break;

nb = next_nb;

nr_to_call--;

}

return ret;

}

代码十分简洁,真的不错,我似乎看到了用c语言实现的Observer模式比OO语言实现的都好,OO中可以通过继承来实现通知-更新的统一化操作,比如所有的观察者继承于同一个抽象的观察者类,然后被观察者发出通知时就可以统一调用观察者抽象类对象的抽象接口了,而是对于c语言来说没有那么多的概念,但是从代码实现上看,更加简洁了,抽象类虽然没有,但是仍然不妨碍c语言组织子类,就是用一个链表,其实就是通知链,于是通知者根本不用管别的只需要调用一个函数就可以了,连什么抽象接口都不用调用,只要调用一个atomic_notifier_call_chain,并且知道通知链就可以了。

有人会说Observer模式和command模式是一样的,但是那只是看起来一样,它们的区别在于,command模式是一种比Observer模式确定的多的行为模式,在command模式中,命令的调用时期是确定的,双方都知道的,之所以用这个模式就是为了将命令的发出者和执行者之间解耦,但是对于Observer就不是这样的,观察者不知道什么时候以及什么情况下会的到通知。command模式更像是一个接力。



 本文转自 dog250 51CTO博客,原文链接:http://blog.51cto.com/dog250/1273649

相关文章
|
1天前
|
存储 算法 Linux
【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化
【Linux】线程的内核级理解&&详谈页表以及虚拟地址到物理地址之间的转化
|
1天前
|
存储 Linux
【Linux】对信号产生的内核级理解
【Linux】对信号产生的内核级理解
|
1天前
|
Linux Shell
Linux操作系统下查找大文件或目录的技巧
Linux操作系统下查找大文件或目录的技巧
|
1天前
|
Linux 编译器 调度
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
本文介绍了如何将POSIX应用程序编译为在Xenomai实时内核上运行的程序。
16 1
xenomai内核解析--双核系统调用(二)--应用如何区分xenomai/linux系统调用或服务
|
1天前
|
算法 Ubuntu Linux
为什么Linux不是实时操作系统
本文探讨了Linux为何不是实时操作系统(RTOS)。实时性关乎系统对事件的确定性响应时间,而Linux虽能保证调度执行的实时任务,但无法确保中断响应时间、中断处理时间和任务调度时间的确定性。中断响应时间受中断屏蔽时间影响,Linux中无法确保;中断处理时间因不支持中断嵌套而不确定;任务调度时间虽快,但调度点的限制影响实时性。Linux的定位是通用操作系统,追求平均性能而非绝对实时性。为改善实时性,Linux提供了不同抢占模型,如可抢占内核(Low-Latency Desktop)和PREEMPT-RT补丁,后者接近硬实时但牺牲了吞吐量。PREEMPT-RT正逐渐成为Linux实时增强的标准。
8 1
为什么Linux不是实时操作系统
|
1天前
|
存储 Ubuntu Linux
xenomai3+linux构建linux实时操作系统-基于X86_64和arm
Xenomai是一个实时性解决方案,通过在Linux上添加实时内核Cobalt来增强实时性能。它有三个主要部分:libcobalt(用户空间实时库)、Cobalt(内核空间实时内核)和硬件架构特定层(ipipe-core或dovetail)。ipipe-core适用于Linux 5.4以下版本,而dovetail用于5.4及以上版本。本文介绍了在X86 Ubuntu环境下,如何编译Xenomai内核,搭建应用环境,包括配置、编译、安装和实时性测试。对于其他硬件架构,如ARM和ARM64,步骤类似。文章还提到了Xenomai与Linux内核版本的兼容性和实时性测试结果。
11 0
xenomai3+linux构建linux实时操作系统-基于X86_64和arm
|
1天前
|
算法 Linux 调度
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
6 1
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(一)--实时端socket创建流程
|
1天前
|
Linux 调度 数据库
|
1天前
|
存储 缓存 Linux
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
本文介绍了Xenomai中的XDDP(Xenomai Distributed Data Protocol)通信机制,XDDP用于实时和非实时进程之间的数据交换。XDDP在Xenomai内核中涉及的数据结构和管理方式,以及创建XDDP通道后的实时端和非实时端连接过程。
7 0
xenomai内核解析--xenomai与普通linux进程之间通讯XDDP(三)--实时与非实时数据交互
|
1天前
|
消息中间件 测试技术 Linux
linux实时操作系统xenomai x86平台基准测试(benchmark)
本文是关于Xenomai实时操作系统的基准测试,旨在评估其在低端x86平台上的性能。测试模仿了VxWorks的方法,关注CPU结构、指令集等因素对系统服务耗时的影响。测试项目包括信号量、互斥量、消息队列、任务切换等,通过比较操作前后的时戳来测量耗时,并排除中断和上下文切换的干扰。测试结果显示了各项操作的最小、平均和最大耗时,为程序优化提供参考。注意,所有数据基于特定硬件环境,测试用例使用Alchemy API编写。
8 0
linux实时操作系统xenomai x86平台基准测试(benchmark)