- 博客(63)
- 收藏
- 关注
原创 设计模式--原型模式(登记形式)
原型模式(登记形式)class Record{public: virtual void print() = 0; virtual Record* clone() = 0; };class CarRecord : public Record{public: CarRecord(string name){ this->name = name; } virtual Record* clone(){ Record* ptr = new CarRecord(name); r
2021-02-01 14:22:23 179
原创 设计模式--原型模式(简单形式)
原型模式class Record{public: virtual void print() = 0; virtual Record* clone() = 0; };class CarRecord : public Record{public: CarRecord(string name){ this->name = name; } virtual Record* clone(){ Record* ptr = new CarRecord(name); return
2021-02-01 14:04:58 215
原创 设计模式--代理模式(强制代理)
代理模式强制代理:真实角色必须通过代理才能访问,并且真实角色的代理的产生,也必须由真实角色决定,与普通代理正好相反;// 签字 class ISign{public: virtual void doSomeThing(string msg) = 0; };// 秘书代理class SecretaryProxy;// 老板 class Boss : public ISign{public: virtual void doSomeThing(string msg){ if(pr
2021-02-01 10:01:18 370
原创 设计模式--代理模式(普通代理)
代理模式普通代理:访问真实对象,通过代理对象来放问真实对象;实现方法:(1)创建代理对象时,传递一个真实对象的引用;(2)在代理类内部实现,在代理类创建时,由代理类决定创建一个真实角色;// 签字 class ISign{public: virtual void doSomeThing(string msg) = 0; };// 老板 class Boss : public ISign{public: virtual void doSomeThing(string msg){
2021-02-01 09:47:22 191
原创 设计模式--适配器模式(缺省适配器)
缺省适配器定义: 为一个借口提供缺省实现,这样的类型可以从这个缺省实现进行扩展,而不必从原有接口进行扩展,当原接口中定义的方法太多,而其中大部分又不被需要时,这种非常有用;// 目标 class IMediaPlayer{public: virtual void play(string fileName) = 0; };// 源 class IAdvacneMediaPlayer{public: virtual void playVlc(string fileName) = 0; v
2021-01-30 13:54:11 214
原创 设计模式--适配器模式(对象适配器)
对象适配器对象适配器是对象的合成关系,也可以说是类的关联关系;对象适配器,相比于类适配器,对象适配器是通过类间的关联关系进行耦合的,因此在设计时就可以做到比较灵活,实际项目中,使用的较多;// 目标 class IMediaPlayer{public: virtual void play(string fileName) = 0; };// 源 class IAdvacneMediaPlayer{public: virtual void playVlc(string fileName
2021-01-30 13:50:11 256
原创 设计模式--适配器模式(类适配器)
类适配器模式类适配器是类间继承,只能通过覆写源角色的方法进行扩展;// 目标 class IMediaPlayer{public: virtual void play(string fileName) = 0; };// 源 class IAdvacneMediaPlayer{public: virtual void playVlc(string fileName) = 0; virtual void playMp4(string fileName) = 0; };class
2021-01-30 13:40:42 142
原创 设计模式--责任链模式
责任链设计模式:// 定义抽象的处理者class LeaderHandler{public: virtual bool handleRequest(int leave_days, LeaderHandlerChain* chain) = 0;};// 定义责任链class LeaderHandlerChain{public: LeaderHandlerChain& addHandler(LeaderHandler* handler){ handlerL
2021-01-30 10:41:53 126
原创 7 重载重写重定义
一、重载(overload)指函数名相同,但是它的参数表列个数或顺序,类型不同。但是不能靠返回类型来判断。(1)相同的范围(在同一个作用域中) ;(2)函数名字相同;(3)参数不同;(4)virtual 关键字可有可无。(5)返回值可以不同;二、重写(也称为覆盖 override)是指派生类重新定义基类的虚函数,特征是:(1)不在同一个作用域(分别位于派生类与基类) ;(2)函数名字相同;(3)参数相同;(4)基类函数必须有 virtual 关键字,不能有 static 。(5)返
2020-06-29 11:31:03 761
转载 2.转载 QT插件实现
1.转载声明:https://www.jianshu.com/p/4498015031042.接口的定义//step 1 定义接口class RegExpInterface{public: virtual ~RegExpInterface() {} virtual QString regexp(const QString &message) = 0;};// step 2// 声明接口// 使用 Q_DECLARE_INTERFACE 宏,是为了让Qt元对象系统知
2020-06-28 11:18:44 220
原创 5.KObject
转载声明:http://blog.chinaunix.net/uid-23253303-id-3923995.html1.介绍kobject, kset, ktype之间的关系:linux 设备驱动模型应用了面向对象的思想,其中,kobject是最基本的基类,其他数据结构都是其派生的产物,通过将kobject嵌入到各个数据结构中,实现了类似的继承关系。举例来说kobject就像是一个普通人,通过额外赋予他不同的职务和工具,使他成为了不同类型的人,比如餐厅的服务员,餐厅的领班等。kobject将各个派生
2020-06-24 11:31:41 276
原创 4.poll接口
1.poll原理poll用来做什么,就是用于在应用层select时候,驱动检查有没有数据可以读的函数。在很多函数里面都要实现。目的就是告诉应用层数据到了。当select时,是否直接返回,还得取决于传入的fd的属性,如果属性是阻塞型,会使用驱动的poll函数做检查,有数据就会返回相应的掩码,如果没有,那么select就在会阻塞,当驱动层有数据到来时,会再一次的调用poll函数做检查,如果有数据了,那么立马会唤醒阻塞的进程或者线程。那么select就会返回。如果不阻塞,当poll检查没有数据时,会立
2020-06-23 18:11:21 661
转载 转载:Linux字符设备中的两个重要结构体(file、inode)
转载声明:http://blog.sina.com.cn/s/blog_72605ba50102xk9r.html1.简介一般而言在驱动程序的设计中,会关系 struct file 和 struct inode 这两个结构体。用户空间使用open()系统调用函数打开一个字符设备时( int fd = open(“dev/demo”, O_RDWR) )大致有以下过程:1.在虚拟文件系统VFS中的查找对应与字符设备对应 struct inode节点;2.遍历字符设备列表(chardevs数组),根
2020-06-23 15:19:50 305
原创 Linux内核常用头文件
1、体系结构相关头文件子目录include/asm这些头文件主要定义了一些与CPU体系结构密切相关的数据结构、宏函数和变量。共4个文件。<asm/io.h>:I/O头文件,以宏的嵌入汇编程序形式定义对I/O端口操作的函数。<asm/uaccess.h> /* copy_to_user, copy_from_user */<asm/memory.h>:内存拷贝头文件,含有memcpy()嵌入式汇编宏函数。<asm/segment.h>:段操作头
2020-06-23 13:29:58 1462
原创 1. QT在linux开发板上显示中文
如果在开发板上显示中文为乱码,可以在QApplication实例之前,添加#include <QTextCodec>QTextCodec::setCodecForLocale(QTextCodec::codecForName("UTF8"));
2020-06-23 11:37:56 412
原创 3.模块依赖EXPORT_SYMBOL
1.依赖的模块#include <linux/init.h>#include <linux/module.h>void depend_func(void){ printk("depend func\n");}EXPORT_SYMBOL(depend_func);static int __init depend_module_init(void){ printk("depend init\n"); return 0;}static void _
2020-06-22 19:31:00 224
原创 2.带参数的可加载模块
1. 定义模块参数的方法:module_param(name, type, perm);其中,name:表示参数的名字; type:表示参数的类型; perm:表示参数的访问权限;2. 数组类型模块参数的定义:用逗号间隔的列表提供的值;声明一个数组参数:module_param_array(name, type, num, perm);其中,name:表示数组的名字; type:表示参数的类型; num :表示数组中元素数量; perm:表
2020-06-22 19:14:43 272
原创 1. 简单的可加载模块
module_init(**_init); // 模块初始化接口module_exit(**_exit); // 模块卸载接口#include <linux/init.h>#include <linux/module.h>static int __init simple_module_init(void){ printk("simple module init.\n"); return 0;}static void __exit simple_mo
2020-06-22 18:46:14 207
转载 转载:fasync的总结
转载声明: https://blog.csdn.net/u010481276/article/details/51093800我们知道,驱动程序运行在内核空间中,应用程序运行在用户空间中,两者是不能直接通信的。但在实际应用中,在设备已经准备好的时 候,我们希望通知用户程序设备已经ok,用户程序可以读取了,这样应用程序就不需要一直查询该设备 的状态,从而节约了资源,这就是异步通知。相关函数原型:int fasync_helper(struct inode *inode, struct file *fil
2020-06-22 13:49:00 303
转载 转载:Linux内核开发之阻塞非阻塞IO----轮询操作
转载声明: https://www.cnblogs.com/hanyan225/archive/2010/10/13/1850497.html使用非阻塞I/O的应用程序通常会使用select()和poll()系统调用查询是否可对设备进行无阻塞的访问,这两个系统调用最终又会引发设备驱动中的poll()函数被执行,所以我们的问题就集中到了如何编写设备驱动中的poll()函数就可以了。二话不说,先来看看设备驱动中的poll()函数原型:unsigned int (*poll)(struct file *fi
2020-06-22 11:56:51 246
转载 linux的I2C驱动——ID匹配
转载: https://blog.csdn.net/Smile_Smilling/article/details/76769201以下基于3.0内核版本的源码进行讲解,驱动代码路径为drivers/misc/eeprom/at24.c。I2C核心代码路径为drivers/I2C模块入口module_init(at24_init);module_init()是一个宏定义,位于include/linux/init.h。如果将驱动编译入内核,定义如下:#define device_initcall(
2020-06-17 16:16:31 456
转载 打开linux内核中dev_dbg的开关
转载:https://www.cnblogs.com/dakewei/p/10082432.html比如要打开某个驱动中的dev_dbg,那么需要在驱动文件.c中这些行"<linux/device.h>“或者”<linux /platfom_device.h>"(device.h包含platform_device.h)之前定义DEBUG如:drivers/mtd/spi-nor/spi-nor.c第一步:#include <linux/module.h>#def
2020-06-17 11:14:18 519
转载 1,proc学习笔记--利用proc 实现内核和用户态交换数据
转载声明:参考该博客 https://www.cnblogs.com/ziziwu/archive/2011/10/20/2218975.html最近写程序需要内核得到用户态的参数,比较苦逼幸福的是虽然ioctrl 用不了,可以用proc实现,proc文件系统提供了一种内核和用户态交互的方法。proc文件系统的详细接口看<linux/proc_fs.h>主要需要关注的是这几个函数:struct proc_dir_entry *proc_mkdir(const char *name, st
2020-06-15 15:39:47 521
原创 6 操作符重载
实现操作符重载: 赋值操作符=, [ ],<<, ==, !=;头文件:#ifndef _MYARRAY_H#define _MYARRAY_H#include <iostream>using namespace std;class MyArray{private: int length; int* space; ...
2020-02-03 23:18:42 181
原创 5 拷贝构造函数的调用时机
C++拷贝构造函数的调用时机有4种:class Test{private: int a; int b; public: Test(int _a, int _b) { a = _a; b = _b; } Test...
2020-02-02 16:17:42 222
原创 1 函数指针知识点
1 声明一个函数类型#include <cstdlib>#include <iostream>using namespace std;void myprint(int a, int b){ cout << a << " " << b << endl;}typedef void (func)(int...
2020-02-01 15:31:22 173
原创 4 const引用知识点
1 指针与引用int val = 20;int& valr = val;int* p = &val;int* &valr2 = p;cout << &val << endl;cout << p << endl;cout << valr2 << endl;cout <&...
2020-01-31 22:56:01 189
原创 3 引用的使用
1 引用作为函数形参#include <cstdlib>#include <iostream>using namespace std;struct teacher{ int id; char name[64];};int getmem_1(teacher** t){ teacher* temp = NULL; ...
2020-01-31 22:14:10 166
原创 2 引用类型
1 引用知识点1 引用没有定义,是一种关系类型声明,声明它和原有某一变量(实体)的关系,故而类型和原类型保持一致,且不分配内存,与被引用的变量有相同的地址。2 声明的时候必须初始化,一经声明,不可变更。3 可对引用,再次引用,多次引用的结果,是某一变量具有多个别名。4 &符号前有数据类型时,是引用,其它皆为取地址。int num = 10; int& p = n...
2020-01-31 17:29:23 253
原创 1 C++语言增强特性
1 命名空间namespace标准命名空间std;命名空间使用方法:方法1:#include <iostream>using namespace std;cout << "hello world" << endl;方法2:#include <iostream>using std::cout;using std::endl;...
2020-01-31 16:48:36 188
原创 通用静态链表
1、头文件定义#ifndef _STATICLIST_H#define _STATICLIST_H#include <stdio.h>#include <stdlib.h>typedef void ListNode;typedef void StaticList;StaticList* StaticList_Create(int capacity);...
2020-01-19 17:37:34 147
原创 7-5 无饿死互斥
参考https://blog.csdn.net/booksyhay/article/details/82769005在如图中所示的程序中,while语句是一个无限循环; 换句话说,一旦线程离开临界区,它就会循环到顶部并尝试再次获取互斥锁。想象一下,线程A获取互斥锁,线程B和C等待。 当A离开时,B进入,但在B离开之前,A循环回来加入到队列中和C一起排队. B离开时,无法保证C接下来会执行。 ...
2020-01-17 16:04:02 346
原创 7-4 写者优先的读者
参考https://blog.csdn.net/booksyhay/article/details/82762278根据应用程序,为写者提供更高的优先级可能是个好主意。 例如,如果写者要对数据结构进行更新,而这种更新又是时序要求很严格的,则最好在写者有机会继续之前,将能查看旧数据的读者的数量控制到最小。初始化osSemaphoreId_t sem_noReaders;sem_noRead...
2020-01-16 19:30:19 267
原创 7-3 读者写者饿死问题
参考https://blog.csdn.net/booksyhay/article/details/82762278在之前的解决方案中,会存在一个问题: 作者可能会饿死。如果写者到达的时候,临界区中有读者,那么当读者来来往往时,它可能会在队列中等待。只要新读者在最后一位读者离开之前到达,房间里总会有至少一位读者。这种情况不是僵局,因为一些线程正在取得进展,但这并不是完全可取的。只要系统上的负...
2020-01-16 19:29:47 1565
原创 7-2 读者写者解决方案封装
与此读者代码类似的模式很常见:进入某个部分的第一个线程锁定信号量(或队列),最后一个线程解锁它。 事实上,它是如此常见,我们应该给它一个名称,并将其包装在一个对象中。模式的名称是Lightswitch,类似于进入房间的第一个人打开灯(锁定互斥锁)的模式,最后一个人将其关闭(解锁互斥锁)。 这是Lightswitch的类定义:typedef struct _LightSwitch{ int...
2020-01-14 19:51:27 195
原创 7-1读者写者问题
参考https://blog.csdn.net/booksyhay/article/details/82762278概念描述:在一些程序中存在读者写者问题,也就是说,对某些资源的访问会 存在两种可能的情况,一种是访问必须是排它行的,就是独占的意思,这称作写操作;另一种情况就是访问方式可以是共享的,就是说可以有多个线程同时去访问某个资源,这种就称作读操作。这个问题模型是从对文件的读写操作中引申...
2020-01-14 19:30:29 329
原创 6-2 有限缓冲区的生产者
参考https://blog.csdn.net/booksyhay/article/details/82743623在6-1中的生产者方案中:尽管这种解决方案是正确的,但仍有机会对其性能进行一次小改进。 想象一下,当生产者发出信号时,至少有一个消费者在队列中。 如果调度程序允许消费者运行,接下来会发生什么? 它会立即阻塞生产者(仍然)持有的互斥锁。阻塞和唤醒是中等昂贵的操作; 不必要地执行...
2020-01-13 20:20:54 363
原创 6-1 生产者-消费者问题
在多线程程序中,线程之间通常存在分工。 在一种常见模式中,一些线程是生产者,一些是消费者。需要强制执行几个同步约束才能使此系统正常工作:在缓冲区中添加或删除项目时,缓冲区处于不一致状态。 因此,线程必须具有对缓冲区的独占访问权限。如果消费者线程在缓冲区为空时到达,则会阻塞,直到生产者添加新项目为止。初始化mutex提供对缓冲区的独占访问。 当items为正数时,它表示缓冲区中项目的数量...
2020-01-11 17:08:20 224
原创 5 独占队列(Exclusive queue solution)
参考 https://blog.csdn.net/booksyhay/article/details/82696779信号量也可用于表示队列。在这种情况下,初始值为0,并且通常编写代码以确保不会发出信号,除非有线程在等待。因此信号量的值永远不会为正数。例如,假设线程代表舞厅舞者,并且有两种舞者:领舞(leaders)和伴舞(followers),在进入舞池之前排队等候。 当领舞到达时,它会检查...
2020-01-11 15:48:18 711
原创 4-3 预装旋转栅门(Preloaded turnstile)
旋转栅门的一个好处是,它是一个多功能组件,可以用于各种解决方案。 但是一个缺点是它迫使线程顺序执行,这可能导致更多的不必要的上下文切换。在可重复使用的屏障解决方案中,如果解锁旋转栅门的线程预先加载旋转栅门,并且有足够的信号让正确数量的线程通过,就可以简化解决方案。初始化osSemaphoreId_t sem_mutex;sem_mutex = osSemaphoreNew(1, 1, N...
2020-01-11 14:46:35 409
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人