- 博客(37)
- 收藏
- 关注
原创 操作系统中的IO多路复用
内核提供的一种事件通知机制,用于实现高性能的I/O多路复用。允许同时监视多个文件描述符,可以在这些文件描述符中的任何一个上等待数据的到达,而不需要为每个文件描述符创建一个单独的线程或进程来处理。可以在一组文件描述符上进行非阻塞的等待,当其中任何一个文件描述符准备好进行I/O操作时,函数返回,并告知哪些文件描述符已经就绪。是事件驱动的,当文件描述符上发生对应的事件时,内核会将该事件通知给应用程序,从而实现了异步的。只会通知活跃的事件,而不是遍历所有注册的文件描述符,因此在有大量非活跃文件描述符的情况下,
2024-04-20 18:10:24
1135
原创 网络编程中的序列化、反序列化与协议
在网络编程中,序列化和反序列化与协议密切相关,它们共同构成了数据在网络中传输的基础。本文将详细介绍序列化、反序列化以及它们与协议之间的关系,以及它们在网络通信中的应用。
2024-03-25 04:26:12
960
原创 mysql 表的约束
外键是一种表的字段,它指向另一个表中的主键或唯一键,从而建立了两个表之间的关系。通常,外键约束主要定义在从表上,从表中的外键列的数据必须在主表的主键列或唯一键列中存在,或者允许为空。
2024-03-14 18:41:12
1105
1
原创 网络编程 TCP/UDP通信
作为程序的入口,从命令行参数获取服务器的端口号,创建TCP服务器套接字,并通过多线程实现与多个客户端的并发通信。: 连接成功后,进入另一个循环,用户可以输入待发送的数据,程序将数据发送到服务器,并等待服务器的回复。: 主函数首先检查命令行参数,确保用户输入的命令行参数为服务器的IP地址和端口号。: 主函数首先检查命令行参数,确保用户输入的命令行参数为服务器的端口号。: 作为程序的入口,从命令行参数获取服务器的IP地址和端口号,创建。: 作为程序的入口,从命令行参数获取服务器的IP地址和端口号,创建。
2024-02-24 04:34:14
1217
原创 网络编程基础
这个字段表示了套接字地址的类型,以便在处理套接字地址时正确地解释其余的结构体字段。在传输过程中,不同协议层对数据包有不同的称谓,如在传输层称为“段”、在网络层称为“数据报”、在链路层称为“帧”。IPv6是IP协议的新版本,为网络提供更多的地址空间。OSI七层模型为网络协议提供了一种清晰的框架,将网络分为七个层次,每个层次负责特定的功能。字段表示地址的协议族,通常是 AF_INET(IPv4)或 AF_UNIX(UNIX 域套接字)。该结构体在套接字编程中扮演着重要的角色,用于指定网络通信的终端地址。
2024-02-23 07:24:02
1571
原创 Linux POSIX信号量 线程池
POSIX信号量是一种用于同步和互斥操作的机制,属于标准的一部分。这一标准定义了操作系统应该为应用程序提供的接口,而POSIX信号量是在多线程和多进程环境下实现同步的一种方式。信号量本质上是一个计数器,用于描述临界资源的数量。在多线程或多进程的情况下,当多个执行单元(线程或进程)需要访问共享资源时,使用信号量可以有效地协调它们的行为,避免竞争条件和提高程序的可靠性。
2024-02-16 19:04:26
981
1
原创 Linux线程 分离和同步与互斥 条件变量
线程分离是指线程在结束时,操作系统会自动回收其资源,而无需其他线程显式地等待它的结束或调用pthread_join函数。这种机制允许主线程不必关心子线程的状态,从而提高程序的并发性和可维护性。
2024-02-09 07:11:41
2976
原创 Linux 线程与pthread库
在Linux系统中,线程控制是多任务编程的核心,而POSIX线程库(pthread库)则是应用层的原生线程库,为开发者提供了丰富的线程控制功能。
2024-02-05 16:14:36
2409
原创 Linux 线程概念
线程是程序执行的最小单位,是进程内的独立执行流。一个进程可以包含多个线程,它们共享大部分资源,包括地址空间、文件和其他系统资源。线程的特点包括最小执行单元、资源共享、轻量级等。在多线程中,线程间可以并发执行,提高程序的效率和响应性。想象你是一名大厨,整个厨房是一个进程。任务如炒菜、烧水,代表在进程内部同时执行的不同任务,如果只有一个炉灶时(单线程),你只能一个一个地做事。如果有多个炉灶时(多线程),你可以同时炒菜、烧水,提高效率。线程就像是并行执行厨房任务,共享厨房资源,让整个烹饪过程更高效。
2024-02-03 05:35:40
1060
原创 信号阻塞与捕捉
信号处理函数执行时,当前信号会被加入进程的信号屏蔽字,防止同类信号再次中断处理。如果需要屏蔽其他信号,可以使用 sa_mask 字段,在处理结束后同样会自动还原。是一个强制终止信号,所以在正常情况下应该避免将其发送给进程,以防止可能导致数据损坏或其他不良后果。:一个信号集,用于指定在执行信号处理函数时需要被屏蔽的信号。进程可以通过修改信号屏蔽集来控制屏蔽和解除屏蔽的信号。:从当前的信号屏蔽字中解除 set 中的信号。中的信号会被阻塞,防止它们干扰当前信号的处理。:将当前的信号屏蔽字设置为 set 中的值。
2024-01-31 21:44:56
945
原创 Linux 信号的产生与处理
系统定义了一系列信号,分为普通和实时信号,每个信号都有编号和宏定义名称。1~31为普通信号,34~64为实时信号。使用 kill -l 命令查看什么是捕捉信号?捕捉信号意味着进程在接收到信号时将执行用户自定义的信号处理函数。如何捕捉信号?// 信号处理函数 - 捕捉信号并执行默认处理动作// 捕捉 SIGINT 信号并设置自定义处理函数pause();// 暂停进程,等待信号发生return 0;在这个例子中,将SIGINT 信号的处理方式设置为custom_handler 函数。
2024-01-29 17:15:20
819
原创 Linux详解共享内存
什么是共享内存?共享内存是操作系统中的一块内存区域,用于多个进程之间直接访问和共享数据。通过获取内存地址,进程可以实现数据的读写操作。共享内存优点适用范围广:可用于父子进程和非父子进程通信。快速访问:直接访问内存,速度相对较快,无需通过文件系统。共享内存缺点不支持阻塞等待:无内建阻塞机制,读写端可以同时访问内存。缺乏访问控制:无法主动停止读写,需要额外的同步机制。
2024-01-27 05:09:06
1344
原创 匿名管道和命名管道
进程间通信是多任务操作系统中不同进程之间进行信息传递的一种机制。它的目的包括数据传输、资源共享、通知事件和进程控制等。管道是进程间通信的一种机制,用于在操作系统中实现不同进程之间的数据传递。它通常被用于具有亲缘关系的父子进程之间。管道在创建时会建立一个缓冲区,用于在进程之间传递数据。这个缓冲区实际上是一个环形队列,允许数据在进程之间实时传递。管道分为两种主要类型:匿名管道和命名管道匿名管道创建方式:pipe()用途:主要用于具有亲缘关系的父子进程通信。生命周期:随创建进程结束而结束命名管道。
2024-01-24 18:42:11
917
原创 制作与使用动态库与静态库
一个库主要包含一批头文件和一个或多个源文件。头文件包含函数声明,源文件包含函数实现。动态库: 在Linux下是后缀为.so文件,在Windows下是后缀为.dll文件。多个程序可以共享使用动态库代码。静态库: 在Linux下是后缀为.a的文件,在Windows下是后缀为.lib的文件。
2024-01-21 19:07:52
946
原创 Linux ext2文件系统 软链接和硬链接
概述: ext2是Linux内核默认采用的文件系统之一,是ext文件系统的第二个版本。它引入了许多改进,如更大的文件名、更大的文件系统和更高的性能。特性不支持日志功能: 与后续版本(如ext3和ext4)不同,ext2没有日志功能,这意味着在系统崩溃时可能需要较长时间来进行文件系统检查和修复。支持软链接和硬链接: ext2支持软链接(symbolic links)和硬链接(hard links),使文件之间的关系更加灵活。支持权限和属性: 类UNIX的权限模型得以保留,文件和目录具有权限、所有者、组等属性。
2024-01-19 17:44:05
902
原创 用户级缓冲区与内核级缓冲区
在 C 语言中,缓冲区(Buffer)是一个用于临时存储数据的区域,通常用于提高输入和输出的性能。由于进程复制,两个进程共享相同的用户级缓冲区,但它们各自有独立的内核级缓冲区。也是使用用户级缓冲区的函数,但由于是二进制写入,不受行缓冲的影响,数据存储在用户空间的缓冲区中,不会立即刷新。这涉及到缓冲区的刷新和进程复制的问题,导致输出在两个进程中交错和重复。都使用了用户级缓冲区,这表示它们将数据存储在用户空间的缓冲区中,而不是直接发送到内核空间。是系统调用,直接操作内核级缓冲区,将数据写入内核空间的缓冲区。
2023-12-30 16:41:32
1286
1
原创 文件操作和文件系统
操作系统通过管理进程的方式,将每个正在执行的进程抽象为 task_struct(PCB),然后通过链表等方式将这些结构体组织起来,以实现对进程的有序调度和管理。:改变数据流的方向,使得数据不再流向默认的设备,而是流向了我们指定的目标,即文件 “log.txt”。上述例子中,我们使用 open 打开(或创建)一个名为 example.txt 的文件,以只写方式打开,如果文件不存在则创建,权限设置为 0644。进程通过文件描述符来管理打开的文件,通过数组指针的方式组织了打开的文件的 file 结构体,
2023-12-28 19:29:41
844
1
原创 简易的自定义Shell实现
首先,让我们了解一下这个自定义Shell的主要功能和结构。基本的命令解析和执行内建命令支持(cd、export、echo)获取用户名、主机名和当前工作目录显示错误代码传递和显示。
2023-12-14 11:09:59
135
1
原创 Linux进程替换
Linux提供了六种exec开头的函数,统称为exec函数族。path:指定可执行文件的路径。arg:以可变参数形式传递命令行参数,以NULL结尾。argv:参数数组,以NULL结尾。file:指定可执行文件的名称,会在PATH环境变量指定的路径中搜索。envp:环境变量数组,以NULL结尾。返回值:如果执行成功,则不返回,否则返回-1,同时设置errno来指示错误的类型。例子// 在PATH=/bin的环境中执行ls命令// 如果execvpe执行失败return -1;
2023-12-10 19:47:02
52
1
原创 位图和布隆过滤器
在大规模数据处理中,常常需要快速判断某个元素是否属于某个集合。传统的数据结构如哈希表能够实现这个目标,但在存储空间和查询效率方面存在一些缺陷。布隆过滤器(Bloom Filter)应运而生,它通过巧妙的设计在占用较少空间的同时提供了高效的查询能力。
2023-12-10 12:40:07
87
1
原创 模拟实现unordered_map和unordered_set
用于从键值对或键中提取键的函数对象(即获取键的操作符函数),在unordered_map和unordered_set中分别为unordered_map和unordered_set的内部类。通过哈希表的基础结构,我们构建了 unordered_map 类,这是一个键-值对的哈希表。: 值的类型,在unordered_map中表示键值对中的值,在unordered_set中则没有对应的值。: 哈希函数,默认为hashfunc,如果键的类型不是整数或字符串,需要提供自定义的哈希函数。
2023-12-03 16:59:40
40
1
原创 Linux进程地址空间
在这个地址空间中,各个区域承担不同的责任,包括内核空间、用户空间的命令行参数和环境变量、栈、共享区、堆、未初始化数据、初始化数据以及正文代码。每个进程都认为它拥有整个虚拟地址空间,但实际上,通过操作系统的地址映射机制,它们对应不同的物理地址。: 虚拟地址空间使得进程管理和内存管理之间的关系解耦,每个进程可以拥有独立的虚拟地址空间,而对物理内存的使用则由操作系统负责。在父子进程中,打印的变量值是不同的,这表明父子进程中的变量确实是各自私有的一份,而不是同一个变量。,而不是真正的物理地址。
2023-11-30 14:34:59
47
原创 wait和waitpid
wait 函数的作用是使父进程一旦调用它就立即阻塞,然后由 wait 自动分析当前进程的子进程是否已经退出。如果找到已经变成僵尸的子进程,wait 会收集这个子进程的信息,彻底销毁它,并随即返回。因此,僵尸进程是指子进程已经退出,但其进程描述符仍然保留在系统中,等待父进程获取相关信息。相比于 wait 函数,waitpid 具有更灵活的特性,可以等待特定的子进程,而不仅仅是等待第一个终止的子进程。如果指定的子进程已经退出,父进程可以在之后的处理中回收子进程。父进程会一直等待,直到指定的子进程退出为止。
2023-11-17 16:27:25
49
1
原创 Linux进程状态和fork函数
具体来说,fork 调用会生成一个新的进程,这个进程是父进程的副本。这种状态通常发生在进程被调试时,调试器会暂停进程的执行以便用户可以检查和修改其状态。对于父进程,返回的是新创建子进程的PID,而对于子进程,返回的是0。当子进程退出时,其信息并不会立即释放,而是保留在PCB中,等待父进程读取。进程处于死亡状态表示它已经完全结束了,所有的资源都已经被释放,不再占用系统资源,死亡状态是非常短暂的。D状态保证了进程在休眠时仍然保持在内存中,以便在特定条件满足时能够及时唤醒,保证了任务的顺利执行。
2023-11-09 12:35:38
61
1
原创 C++虚表和动态绑定
在动态绑定中,关键的机制是虚函数和虚表。通过基类指针或引用指向派生类对象时,可以在运行时根据对象的实际类型调用相应的虚函数。每一个包含虚函数的类都拥有自己的虚表,这个虚表属于类而不是具体的对象。虚函数(Virtual Function)在C++中,通过在类中声明一个函数为virtual,可以将其定义为虚函数。虚表指针(Virtual Pointer)是一个指向虚函数表的指针,虚函数表是一个包含虚函数地址的数组。通过基类指针或引用指向派生类对象时,可以在运行时根据对象的实际类型调用相应的虚函数。
2023-11-04 11:14:01
70
1
原创 二叉搜索树的插入和删除操作
二叉搜索树是一棵具有以下性质的树:1.左子树上所有节点的值均小于其父节点的值。2.右子树上所有节点的值均大于其父节点的值。3.左右子树也分别为二叉搜索树。
2023-11-04 08:45:06
215
1
原创 C++ 中的仿函数、非类型模板参数和模板特化
在C++中,仿函数(Functors)是一种行为类似于函数的对象。它们是通过重载了operator()来实现的,使得对象可以像函数一样被调用。C++中的模板允许我们将类型和数值作为参数传递。非类型模板参数是在模板声明中使用非类型(如整数、枚举等)作为参数的一种方式。模板特化是一种在特定条件下为模板提供定制实现的机制。它允许我们为特定类型或值提供特定的实现。模板特化的前提是你已经定义了一个通用模板。
2023-10-08 17:13:46
129
1
原创 Linux gdb的基础操作
GDB(GNU Debugger)是一个强大的开源调试器,用于在程序运行时诊断和解决 bug。它支持多种编程语言,包括C、C++、Fortran等,并且可以在多种操作系统上运行,包括Linux、macOS等。
2023-09-28 16:21:03
147
1
原创 程序的编译过程和Linux gcc
程序的编译过程是将高级编程语言代码转换成计算机能够理解和执行的低级机器语言代码的过程。这个过程通常包括:预处理->编译->汇编->链接。
2023-09-11 20:44:47
61
原创 Vim的基本模式
Vim(Vi Improved)是一款强大的文本编辑器,特别适用于Linux系统。它具有高效的编辑和导航功能,但可能需要一些时间来熟练掌握。下面是一份简单的 Vim 使用介绍。
2023-09-09 22:11:08
204
1
原创 Linux 常用命令
文件所有者默认权限为666(110 110 110 == rw- rw- rw-),umask 022 后,减去相应位的权限,最终为644 (rw-r–r–)在Linux中,umask是用来控制新文件和目录的默认权限的设定。目录默认权限为777(111 111 111 == rwx rwx rwx),umask 022 后,减去相应位的权限,最终为755 (rwxr-xr-x)使用粘滞位是为了确保共享目录下的文件只能被创建者或管理员删除,这在一些公共或共享目录中非常重要,以保护目录中的文件不被随意删除。
2023-09-07 16:45:27
51
空空如也
空空如也
TA创建的收藏夹 TA关注的收藏夹
TA关注的人