自定义博客皮肤VIP专享

*博客头图:

格式为PNG、JPG,宽度*高度大于1920*100像素,不超过2MB,主视觉建议放在右侧,请参照线上博客头图

请上传大于1920*100像素的图片!

博客底图:

图片格式为PNG、JPG,不超过1MB,可上下左右平铺至整个背景

栏目图:

图片格式为PNG、JPG,图片宽度*高度为300*38像素,不超过0.5MB

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+
  • 博客(34)
  • 收藏
  • 关注

原创 Yocto构建Linux系统镜像时,git下载出错/慢、常见问题的解决方案

如图,有时在使用git下载github上的相关内容时,时常会因为网络原因导致下载失败进而构建失败。加速下载相关裸仓库(我这里使用的github desktop),替换其git2内的相关文件,然后修改配方文件,将远程仓库链接改为本地链接,即可成功解决问题。另外在do_install的时候,出现了删除一个文件,但文件不存在报的警告,却中止了整个install进程。,如xxx.tar.gz有直接的下载链接,那么只需要自己在主机下载好文件,放入构建目录的下的downloads文件夹即可。这里我就修改了git路径。

2024-04-25 14:51:52 604

原创 Linux内核,块设备和字符设备

在 Linux 和其他类 Unix 操作系统中,设备通常被分类为块设备和字符设备。

2024-04-25 14:17:47 335

原创 Linux内核初探(5)IO多路复用技术

内核遍历文件描述符列表,对设备调用其poll方法,poll方法会检查设备状态,若设备可用,则返回一个非0值(这里是POLLIN | POLLRDNORM),若设备不可用,则会将当前进程添加到等待队列,如果。但是目前阻塞住了IO的话,即让调用该驱动的程序睡眠,那么会导致若有其他信息需要唤醒程序,而这个就会被阻塞在此程序处,导致程序无法运行。,无论当前设备是否可用,都将该进程加入等待队列以方便在可用的时候唤醒进程。此函数的前者为将等待的进程放入等待的状态,第二个参数为进程的。,然后进行相应的读或写操作。

2023-11-27 19:06:28 70

原创 一文弄清TCP/IP协议常见考点

如果客户端在发送完最后一个ACK报文后立即关闭连接,那么如果这个ACK报文在网络中丢失,服务端就会因为没有收到确认而重新发送FIN报文,但是这个时候客户端已经关闭了连接,就无法对这个FIN报文进行响应,导致服务端一直等待,无法关闭连接。第二次握手 server---------------------------------------------》client。第一次握手 server 《---------------------------------------- client。

2023-11-23 23:20:57 108

原创 Linux内核初探(5)内核内存直接访问

MAP_PRIVATE 对应射区域的写入操作会产生一个映射文件的复制, 即私人的"写入时复制" (copyon write)对此区域作的任何修改都不会写回原来的文件内容.MAP_FIXED 如果参数 start 所指的地址无法成功建立映射时, 则放弃映射, 不对地址做修正.通常不鼓励用此旗标.MAP_DENYWRITE 只允许对应射区域的写入操作, 其他对文件直接写入的操作将会被拒绝.MAP_SHARED 对应射区域的写入数据会复制回文件内, 而且允许其他映射该文件的进程共享.

2023-11-21 19:04:08 109

原创 Linux内核初探(4)次设备号的概念和用途

在 Linux 中,inode 是文件系统中的一个重要概念,它包含了关于文件系统对象(如文件和目录)的元数据,例如权限、所有者、大小、创建时间等。inode告诉你该设备文件固有信息,即元数据,包括主设备号和从设备号的信息。使用iminor函数可以获取元数据中的从设备号信息,通过从设备号来判断初始化哪个设备。当应用层有多个设备号,但这些设备号是同一个设备驱动,那么就需要在内核层提取来自应用层中的设备号。我们可以通过这个参数在获取到初始化中来自应用层打开的设备文件的次设备号来决定控制哪个设备。

2023-11-20 17:04:31 124

原创 Linux内核初探(3)内核与app层的通信

在Linux中,ioctl系统调用可以用于在用户空间和内核空间之间传输数据。以下是一个简单的例子,说明如何使用ioctl和一个数据结构在内核和应用程序之间传输数据。在这个例子中,应用程序首先打开设备文件,然后使用ioctl系统调用来设置和获取值。在内核驱动中,ioctl函数根据命令来设置或获取值,并将结果存储在数据结构中。之前说到了app通过ioctl控制内核层。

2023-11-14 10:08:11 122

原创 Linux内核驱动初探(2)

当进程调用open函数打开一个文件或设备时,内核会在文件描述符表中添加一个新的条目,并返回一个文件描述符。创建管道时,内核会在两个进程的文件描述符表中各添加一个新的条目,一个用于读取管道,一个用于写入管道。这样,一个进程可以写入管道,另一个进程可以从管道中读取数据,从而实现进程间的通信。当创建新的子进程时,子进程会复制父进程的文件描述符表,从而继承父进程打开的所有文件和设备的文件描述符。但需要注意的是,这些文件描述符在子进程中是独立的,也就是说,子进程对文件描述符的操作不会影响父进程。

2023-11-14 10:05:41 26

原创 Linux内核模块初探

在你的驱动程序中,使用alloc_chrdev_region函数分配了一个设备号,这个函数会返回一个主设备号和一个次设备号。这行代码的意思是请求分配一个字符设备号,第一个次设备号是 0,设备数量是 1,设备的名称是 "led"。在驱动程序中,使用cdev_add函数注册了一个字符设备,这个设备关联了设备驱动程序和一个设备号。通过链表,链表存储函数指针,那么当open后,就在链表中找设备,在设备中找到真正所需要的函数,若有新设备,也可以通过链表添加。字符设备结构体代表了字符设备驱动程序中的设备。

2023-11-13 19:03:36 46

原创 虚拟内存和物理内存之间的关系

各个进程要吃饭(即利用内存资源执行任务),那么吃饭一个一个地吃,若饭量小的人,吃饭一时间用不了那么大的碗,但又占用了其他人吃饭的时间,效率极低。阐述以下自己的理解:首先需要理解物理内存的概念,物理内存为实际的内存,但是对于操作系统而言,会“同时”运行多个进程,那么就可能导致实际的物理内存不够使用。若频繁发生页面交换,那么就会导致开销较大。并且,虚拟内存中的地址是连续的,但是实际的物理内存的内存的页面可能会被分散在不同的位置,即片区不同(即一个大碗由多个小碗组成)切换页面会导致开销,会降低一定的运行速度。

2023-11-10 20:22:21 229

原创 Makefile中的参数---obj

例如,drv-objs := func.o module.o 表示 drv.o 模块由 func.o 和 module.o 这两个对象文件组成。例如,obj-y := func.o 会将 func.o 直接编译到内核中。例如,obj-m := drv.o 会构建一个名为 drv.o 的内核模块。例如,obj- := drv.o 会构建 drv.o,但不指定它的类型。例如,obj-n := module.o 会排除 module.o。在Linux内核编程中,obj是一个特殊的前缀,用于指定要构建的目标。

2023-11-09 19:06:32 455

原创 QT中的数据库操作

【代码】QT中的数据库操作。

2023-10-17 09:27:04 76

原创 deque 的底层实现

当我们要访问一个元素时,我们首先通过索引数组找到对应的块,然后在块中找到对应的元素。这种数据结构允许我们在两端进行高效的插入和删除操作,因为我们只需要修改索引数组和对应的块,而不需要移动所有的元素。块0: | 0 | 1 | 2 | 3 | ... | n |块1: | 0 | 1 | 2 | 3 | ... | n |块2: | 0 | 1 | 2 | 3 | ... | n |索引数组: | 0 | 1 | 2 | 3 | 4 |对应的块: | * | * | * | * | * |

2023-09-27 15:33:55 137

原创 虚函数中的多态

例如,我们可以定义一个虚类Shape,它有一个纯虚函数area。虚类Shape定义了一个接口,即所有形状都应该能够计算面积,但它没有指定如何计算面积,这是由派生类来决定的。纯虚函数是在基类中声明但没有定义的虚函数,它在基类中的声明形式为 virtual void func() = 0;这是因为虚类不完全,它包含至少一个没有定义的函数。虚类主要用于定义接口,派生类继承虚类并实现其纯虚函数,从而成为一个可以实例化的完全类。举个例子,现有一个animal的基类,其定义有一个叫的虚类函数。

2023-09-25 19:58:23 35

原创 基于TCP/IP通信的云盘项目

本项目用到了多线程多,TCP/IP,数据库,状态机的相关知识。但是还有接收文件和上传文件的线程还没完善,暂只能实现多客户端的单个上传/下载请求。未来有空实现更改工作目录,实现一个账户一个目录即真正实现私人云盘功能。

2023-09-15 19:30:32 112 1

原创 pthread_detach和pthread_join

例如,创建了一个处理客户端请求的线程,不需要知道这个线程何时结束,也不需要获取它的退出状态,只希望这个线程在处理完客户端请求后能自动结束并回收其资源,那么就应该使用pthread_detach。pthread_join和pthread_detach都是处理线程结束时的资源回收问题,但是pthread_join需要阻塞等待线程结束并获取其退出状态,而pthread_detach则是设置线程为自动回收资源的状态。1. 如果需要等待一个线程结束,并获取它的退出状态,那么应该使用pthread_join。

2023-09-13 10:36:54 988 2

原创 无名管道、有名管道

无名管道只能用于具有亲缘关系的进程之间的通信,即父进程创建子进程后,它们之间可以通过无名管道进行通信。与无名管道不同,有名管道在文件系统中有一个相关的路径名,并且可以通过该路径名在不同的进程之间进行通信。需要注意的是,创建的有名管道既可以被读取进程打开,也可以被写入进程打开。总结来说,无名管道用于具有亲缘关系的进程之间的单向通信,而有名管道用于不具有亲缘关系的进程之间的双向通信,并且有一个相关的路径名。- 管道的大小是有限的,一旦管道被填满,写入进程将被阻塞,直到有进程读取管道中的数据。

2023-09-01 19:04:09 160 1

原创 typedef取对结构体取别名

而使用结构体标签定义变量时,需要先使用标签定义结构体类型,然后再使用标签来声明变量。seqlist_q 是一个指向 seqlist 结构体类型的指针别名,也是通过 typedef 关键字定义的。总结一下,list 是结构体标签,seqlist 是结构体类型的别名,seqlist_q 是指向 seqlist 结构体的指针类型的别名。使用结构体类型别名定义变量的方式是直接使用别名来声明变量,而使用结构体标签定义变量的方式是先使用标签定义结构体类型,然后使用标签来声明变量。

2023-09-01 17:04:58 147 1

原创 进程线程中,exit\_exit\return\pthread_exit各函数的含义以及区别

如果在分离状态的线程中调用pthread_exit(),则该线程会立即结束,不会影响其他线程或进程。与exit(-1)不同,pthread_exit(NULL)只会终止当前线程的执行,而不会终止整个程序的执行。在main()函数中使用return和在main()函数中调用exit()是等价的。总的来说,exit()和_exit()是用于结束进程的,而pthread_exit()是用于结束线程的。- pthread_exit(NULL)会立即终止当前线程的执行,但不会终止整个程序的执行。

2023-09-01 10:52:51 545 1

原创 有名管道全双工通信

【代码】有名管道全双工通信。

2023-09-01 09:31:23 71 1

原创 waitpid和wait函数

如果子进程还在运行,父进程可以继续等待。1、在需要等待子进程结束时,可以使用wait函数,其中wait函数获取任意一个子线程退出的状态,若有多个子进程,则需要多次使用wait函数。要避免孤儿进程(即子进程在父进程结束后仍然在运行),可以使用waitpid函数来等待子进程的结束,并确保子进程在父进程结束之前完成。需要注意的是,父进程在等待子进程结束时,可以执行其他操作,以充分利用时间。wait函数无法等待指定pid结束,并且wait函数是阻塞当前的父进程,会导致效率较低,因此引入waitpid函数。

2023-08-31 15:05:02 98

原创 线程中的管道,生产线程,消费线程,互斥,条件变量

在消费者函数中,同样通过互斥锁保护临界区,当缓冲区为空时,消费者线程会等待条件变量cond_consumer的信号,直到缓冲区有数据后才继续消费数据。通过使用条件变量,生产者和消费者线程可以在合适的时机等待和通知,避免了忙等待(busy-waiting)的情况,提高了线程的效率和性能。这段代码实现了生产者-消费者模型,通过互斥锁和条件变量实现了线程间的同步和互斥,确保生产者和消费者线程正确地生产和消费数据。条件变量(pthread_cond_t)是一种线程同步机制,用于在线程间进行条件的等待和通知。

2023-08-31 08:00:00 41

原创 线程的同步和互斥

当线程执行P操作时,如果资源可用(信号量的值大于0),线程将继续执行,并将信号量的值减1,表示占用了一个资源。它会尝试获取信号量,如果信号量的值大于0,则将信号量的值减1,并继续执行。当一个线程完成对共享资源的访问时,它需要释放信号量资源,以便其他线程可以获取资源并继续执行(通过调用sem_post()函数)。通过使用sem_wait()和sem_post()函数,可以控制线程对共享资源的访问,确保线程按照预期的顺序执行,并避免竞争条件和数据不一致的问题。当信号量的值大于0时,表示有可用的资源。

2023-08-30 23:47:12 48 1

原创 fread和fgets和fgetc和fwrite和fputs的区别

例如,fread(buffer, sizeof(int), 10, file) 将从文件中读取 10 个 int 类型的数据项到 buffer 中。- fread 和 fgets 返回实际读取的数据项数量或读取的文本行,而 fgetc 返回读取的字符的 ASCII 值。- fgets 会在读取到换行符或达到最大字符数时停止读取,而 fgetc 可以连续读取文件的每个字符。- fread 用于读取二进制数据,fgets 用于读取文本行,fgetc 用于读取单个字符。

2023-08-30 14:30:49 521 1

原创 线程基础、线程的:创建、同步、退出、取消

线程在进程之下,主要是因为进程由于具有自己的独立的地址空间,在进程间切换会有较大的开销,为了方便切换提升系统性能,引入线程的概念。即在同一个进程中创建的线程共享该进程的地址空间。类似于进程中的wite函数,ptherd_join函数(同步)。

2023-08-29 10:29:05 107

原创 进程的学习

进程由程序,数据集合,进程控制块(PCB)组成进程控制块是用来描述进程的当前状态,本身特性的数据结构,是进程中组成的最关键部分,其中含有描述进程信息和控制信息,是进程的集中特性反映,是操作系统对进程具体进行识别和控制的依据。PCB一般包括:1.程序ID(PID、进程句柄):它是唯一的,一个进程都必须对应一个PID。PID一般是整形数字2.特征信息:一般分系统进程、用户进程、或者内核进程等3.进程状态:运行、就绪、阻塞,表示进程现的运行情况4.优先级:表示获得CPU控制权的优先级大小。

2023-08-27 15:57:22 36 1

原创 文件 IO(系统调用)

1. 行缓存(line buffering):行缓存是指在输入输出操作中,数据会被缓存在缓冲区中,直到缓冲区被填满或者遇到换行符 \n。在行缓存模式下,输出函数如 printf 会将数据先写入缓冲区,直到遇到换行符或者缓冲区被填满,才会将缓冲区的内容一次性地写入文件。输入函数如 fgets 会将一行完整的数据读取到缓冲区中,直到遇到换行符或者缓冲区被填满,才会将缓冲区的内容一次性地返回。2. 全缓存(fully buffering):全缓存是指在输入输出操作中,数据会被缓存在缓冲区中,直到缓冲区被填满。

2023-08-25 10:20:56 46 1

原创 标准IO(库函数)

它的作用是将格式化的数据按照指定的格式写入到一个字符串中,而不是输出到屏幕上,它可以格式化数据,也可以组合两个字符串。作用:向指定流中输出单个字符,其中,c是要写入文件的字符的ASCII码值,stream是一个指向已打开文件的指针。sprintf函数将格式化后的字符串写入到str指向的字符数组中,并返回写入的字符数(不包括终止符\0)。fgets函数返回一个指向str的指针,如果成功读取到字符串,则返回str的值;其中,filename是一个字符串,表示要打开的文件的路径和名称;

2023-08-24 10:33:05 293 1

原创 单向链表的冒泡排序

今天在对链表进行冒泡排序的时候遇到了一点困难,仔细思考后才发现是自己冒泡排序的理解不够透彻。对于单向链表,由于数据是单个数据,不能用数组的冒泡排序生搬硬套。

2023-08-22 20:23:30 112 1

原创 分块查找

总结来说,分块查找是一种基于块的查找算法,通过将数据分为若干个块,并在每个块内部有序排列,以实现快速定位目标元素。然而,分块查找的缺点是需要额外的空间来存储块的索引和块内的元素。通过以上步骤,我们可以保证块之间的元素的最大值要小于下一个块的最小值,从而确保块之间的元素没有重叠。- 调整块内元素的排序:可以重新排序块内的元素,使得最大值小于下一个块的最小值。- 调整块的大小:可以增加块的大小,使得最大值小于下一个块的最小值。3. 块之间的元素的最大值要小于下一个块的最小值,以确保块之间的元素没有重叠。

2023-08-22 11:22:40 552 1

原创 数据结构-算法

通过指针传递是将结构体指针传入函数,可以避免在函数调用时复制整个结构体对象的开销,同时也可以在函数内部修改结构体对象的内容。注意,函数内传入的是地址,若在主函数内通过类型定义结构体,则需要对其取地址int data;} MyStruct;return 0;在使用tyoedef定义定义结构体时,有两种取别名的方式:取结构体类型别名 取指针别名。int data;MyStruct 是一个别名,它代表了一个结构体类型。通过使用 MyStruct,我们可以定义结构体变量、传递结构体参数等。

2023-08-17 19:39:37 29 1

原创 gcc编译器、gdb调试、Makefile学习

条件编译 #if #else #endif #elif。Makefile是make工具的唯一配置文件,文件名只能叫makefile。-I(i的大写) :需要引用的头文件路径。该脚本是初级理解,代码会逐行检查依赖,若没有,就会用接下来的代码生成。要使用gdb调试在编译时必须加上-g选项。gdb +p:变量名,查看变量的内容。gdb +b:在对应行设置一个断点。gdb +l:查看十行代码内容。make是一个工程管理器,用来管理多文件项目的。gdb +r:让程序执行一次。gdb +n:让程序继续运行。

2023-08-16 22:47:09 145 1

原创 c高级学习

结构体是一种自定义的数据类型,用于将不同类型的数据组合在一起形成一个新的数据类型(相当于int这些数据类型,int这些如何定义变量,结构体便如何定义)。它允许我们在一个单独的变量中存储和操作多个相关的数据。结构体内的各个元素的类型不同,且是这些不同类型的元素的集合。虽然有点像数组的定义(同种元素的有序集合),但结构体数组和结构体是两个意义。在理解结构体的时候还是把它当作一个特殊的数据类型好一些(如特殊的int?)或者说,一个对象的大属性,大属性内包含小属性。

2023-08-16 09:27:22 19

原创 指针数组利用二级指针的输入和输出

指针学习

2023-08-14 20:29:58 626 2

空空如也

空空如也

TA创建的收藏夹 TA关注的收藏夹

TA关注的人

提示
确定要删除当前文章?
取消 删除