自定义博客皮肤VIP专享

*博客头图:

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

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

博客底图:

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

栏目图:

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

主标题颜色:

RGB颜色,例如:#AFAFAF

Hover:

RGB颜色,例如:#AFAFAF

副标题颜色:

RGB颜色,例如:#AFAFAF

自定义博客皮肤

-+

[email protected]的博客

Before was was was, was is is.

  • 博客(118)
  • 收藏
  • 关注

原创 C++内存模型

CPU 体系都是基于栈来运行程序,栈中主要存放函数的局部变量、函数参数、返回地址等,栈空间一般由操作系统进行默认分配或者程序指定分配,栈空间在进程生存周期一直都存在,当进程退出时,操作系统才会对栈空间进行回收。

2024-05-20 13:01:08 801

原创 C++:再谈智能指针

通过使用 std::make_unique,确保每次内存分配和对象构造都立即被 unique_ptr 接管。如果构造函数抛出异常,unique_ptr 从未被创建,但因为异常是在 make_unique 内部抛出的,已分配的内存会在抛出异常前由内部机制(通常是函数的栈展开)释放,这就避免了内存泄漏。

2024-05-18 22:22:57 1198

原创 C++调试:函数调用过程和堆栈

最后两条指令是函数结尾处的序曲,通常称作函数的 epilogue(尾声),它们的主要作用是恢复函数开始时保存的状态,并释放栈空间,以便函数可以正确地返回到调用者。

2024-05-17 16:43:00 755

原创 C++调试:内存管理

简而言之,S 和 B 都涉及未初始化的数据,但它们代表的是不同的内存区段。S 不属于 B,但两者都用于未初始化数据的存储,只是大小和存储优化方面有所区别。因此,在处理大型和小型未初始化数据时,编译器和链接器可能会选择将它们分别放在 .bss 或 .sbss 段中。

2024-05-16 22:44:48 236

原创 C++并发:构建线程安全的队列

在 threadsafe_queue 的拷贝构造函数中,尽管传入的 other 对象是一个 const 引用,我们仍然需要从这个 const 对象中复制数据。拷贝构造函数需要访问 other 对象的 data_queue,而为了线程安全,必须先锁定 other 的互斥量。由于 mut 是 mutable 的,即使在 const 上下文中,也能执行锁定操作。

2024-05-15 17:44:36 395

原创 C++并发:等待条件成立

故此,若判定函数有副作用,则不建议选取它来查验条件。 倘若真的要这么做,就有可能多次产生副作用,所以必须准备好应对方法。譬如,每次被调用时,判定函数就顺带提高所属线程的优先级,该提升动作即产生的副作用。结果,多次伪唤醒可“意外地”令线程优先级变得非常高。

2024-05-15 16:10:02 700

原创 C++:并发保护

std::call_once() 保证无论多少线程尝试调用指定的可调用对象,该对象的调用只会执行一次。它通过 std::once_flag 来控制,这个标志协调不同线程对函数调用的访问,确保目标函数只执行一次。

2024-05-14 21:57:45 987

原创 C++并发:锁

在C++中,std::lock 是一个用于一次性锁定两个或多个互斥量(mutexes)的函数,而且还保证不会发生死锁。这是通过采用一种称为“死锁避免算法”的技术来实现的,该技术能够保证多个互斥量按照一定的顺序加锁。

2024-05-14 17:38:26 843

原创 C++:完美转发(二)(std::forward)

C++中常量一般是进入符号表的,只有对其取地址时才会实际分配内存。 调用 f 函数时,其实参是直接从符号表中取值,此时不会发生问题。但当调用 fwd 时由于其形参是万能引用,而引用本质上是一个可解引用的指针。 因此当传入 fwd 时会要求准备某块内存以供解引用出该变量出来。但因其未定义,也就没有实际的内存空间, 编译时可能失败(取决于编译器和链接器的实现)。

2024-05-12 23:30:46 938

原创 C++:完美转发(一)(std::forward)

std::forward 函数模板的实现,这是完美转发的关键机制。完美转发是指在模板函数中将参数维持原样(保持其值类别——左值或右值)传递给另一个函数的技术。std::forward 通常在实现需要将参数转发到其他函数的模板中使用,尤其是在构造函数、函数模板和其他接受任意参数的场景中。

2024-05-12 20:54:02 1125

原创 C++:移动语义(std::move)

移动语义允许资源(如动态内存)在对象间转移,而非复制,这可以显著提高性能,尤其是对于大型对象。移动构造函数和移动赋值操作通常应声明为noexcept以确保在资源转移过程中不抛出异常,这是因为异常可能导致资源泄露或其他问题。实现移动操作时,应确保正确处理自赋值的情况和资源的安全释放。

2024-05-11 23:43:16 896

原创 C++:左值(引用)&右值(引用)

需要注意的是,func() 中的 b 其实是一个左值,换句话说,右值引用如果绑定了一个右值,它会延长这个右值的生命周期。 这种生命周期的延长意味着,尽管原始表达式产生的值是一个右值,一旦它被一个右值引用所绑定,它就不再是一个"即将销毁的临时值",而更像是一个普通的变量。 这允许开发者在保证效率的同时,也能够更灵活地控制这些值。

2024-05-10 22:09:59 995

原创 C++并发:线程函数传参(二)

当向线程函数传参时,可能发生隐式类型转换,这种转换是在子线程中进行的。需要注意,由于隐式转换会构造临时对象,并将该对象(是个右值)传入线程函数,因此线程函数的形参应该是可接受右值类型的T、const T&或T&&类型,但不能是T&类型。此外,如果源类型是指针或引用类型时,还要防止可能发生悬空指针和悬空引用的现象。

2024-05-10 00:10:13 328

原创 C++并发:线程函数传参(一)

遇到的错误与尝试在 std::thread 构造器中使用不匹配的参数类型有关。错误的根本原因是在创建 std::thread 实例时传递的参数类型与线程函数所期望的参数类型不兼容。因此我们要考虑,传递的参数如何才能正确兼容线程函数期望的参数类型。这正是上面讨论到的一种情况,接着讨论如何优雅的解决这种问题。

2024-05-09 23:39:44 424

原创 macOS DOSBox 汇编环境搭建

这个配置文件在启动 DOSBox 时会被加载并生效。其中的 [autoexec] 部分包含了一些命令,这些命令会在 DOSBox 启动时自动执行。这些命令通常用于配置 DOSBox 的一些初始设置,例如挂载游戏的磁盘镜像、设置运行环境等。

2024-05-05 22:35:14 491 1

原创 CM3:lldb 调试 qemu 跑的程序

QEMU可以通过启动一个GDB调试端口来允许使用GDB调试正在运行的虚拟机,我们要做的就是通过 gdb 或者 lldb 连接到这个端口,然后进行调试。

2024-04-28 11:50:57 850

原创 CM3:qemu执行汇编

lm3s6965evb 是 Luminary Micro 的 Cortex-M3 处理器(LM3S6965)的一种开发板型号,这个命令告诉 QEMU 使用 LM3S6965 Cortex-M3 处理器模拟器,在终端中以无图形界面模式运行,并加载名为 hello.bin 的内核镜像文件。

2024-04-27 13:14:57 564

原创 8086:qemu执行汇编

当使用qemu-system-i386命令并提供一个二进制文件作为参数时,QEMU会尝试以i386架构的处理器来执行这个二进制文件。虽然这个二进制文件不是一个完整的操作系统或磁盘镜像文件,但QEMU仍然可以尝试执行它,并显示输出结果。

2024-04-26 23:33:14 560 1

原创 C++:函数符(一)

相比之下,我们可以使用函数对象或者 lambda 表达式作为 std::for_each 的第三个参数,因为它们都是可调用对象。函数对象是一个类,重载了 operator() 运算符,可以像函数一样被调用。Lambda 表达式也是一个可调用对象,可以在需要时直接定义并使用。

2024-04-24 22:00:35 383

原创 C++:适配器

这些适配器类模板使得在不同场景下可以方便地使用不同的容器实现,同时提供了统一的接口,使得代码更加灵活和可复用。通过使用 STL 提供的适配器,可以更加方便地构造具有特定功能的容器,满足不同的需求。因此,stack、queue、priority_queue不被称为容器, 把它称为容器配接器。

2024-04-24 21:30:19 380

原创 C++:迭代器

需要注意的是,各种迭代器的类型并不是确定的,而只是一种概念性描述。 正如前面指出的,每个容器类都定义了一个类级 typedef 名称——iterator,因此 vector 类的迭代器类型为vector ::interator。然而,该类的文档将指出,矢量迭代器是随机访问迭代器,它允许使用基于任何迭代器类型的算法,因为随机访问迭代器具有所有迭代器的功能。

2024-04-23 21:45:57 613

原创 C++:智能指针(二)

这些智能指针的选择取决于所需的所有权模型和内存管理策略。使用适当的智能指针可以大大简化代码,提高程序的可维护性和可靠性。

2024-04-21 23:52:29 750

原创 C++:智能指针(一)

文章展示了如何正确地使用unique_ptr对象作为容器元素,并对show()函数的参数传递方式进行了解释,强调了按引用传递参数的重要性,以避免不必要的复制操作和编译错误。

2024-04-21 23:18:59 418

原创 C++:返回值优化

这种优化称为返回值优化(Return Value Optimization,简称 RVO),它能够提高程序的性能并减少不必要的对象拷贝。在这种情况下,编译器将对象直接构造在函数调用方指定的内存空间中,而不是通过复制构造函数创建临时对象。

2024-04-17 19:25:57 360

原创 C++:异常处理

可以看到catch()的参数尽管可以被设为引用,但是其实仍然要发生异常对象的复制(用复制构造函数)。如果没有被设置为引用,那么在最后,不仅要析构异常对象副本,还要析构异常对象本身。

2024-04-17 18:01:19 336

原创 C++:弃值表达式

弃值表达式是一种编程技巧,用于清除不必要的警告或明确表示我们不关心某些表达式的返回值,而只关注它的副作用。

2024-04-11 20:41:12 305

原创 关于一篇知乎答案的重现

实现了一个简单的容器化环境的初始化过程,包括命名空间的隔离、文件系统的挂载与切换、进程环境的修改等操作,从而创建了一个隔离的运行环境。

2024-03-31 17:20:23 248

原创 2023 个人总结

这一年是成长的一年,记录一些感悟。这里没有吃吃喝喝与娱乐休闲,主要是对自己过去的总结、反思以及对未来的展望。

2023-12-31 17:57:27 993 2

原创 mit6.s081【目录】

现在是 2023 年 12 月 24 日,我终于完成了 mit6.s081课程的学习,期间读完了xv6book、OSTEP、xv6 部分内核源码,也写了 近 20 篇的博客,可以说是学习之旅收获颇丰。本文将会起一个目录,方便查找和阅读。

2023-12-24 19:08:07 209

原创 MIT 6.S081学习笔记(第十章)

实现对于完成 MIT 6.S081 实验中的网络部分非常详细和全面。e1000_transmit() 函数有效地将数据包发送到 E1000 网卡中,涵盖了缓冲区描述符的正确设置和释放,并确保了发送队列的并发安全性。e1000_recv() 函数则能够持续地处理接收到的数据包,在循环中检查描述符的状态并进行数据包处理、网络栈传递和接收队列更新等操作。

2023-12-24 18:41:41 150

原创 MIT 6.S081学习笔记(第九章)

实验的目标是确保实现 mmap 和 munmap 功能,使得测试程序 mmaptest 能够成功运行,并通过一系列测试,包括对 mmap 和 munmap 的功能、文件的读写、进程 fork 和 exit 的正确性检验等。

2023-12-23 22:22:25 187

原创 Shell Tools of Missing Semester(二)

bash中的字符串使用'和"定义,每种方式有不同的含义。'定义的字符串为原义字符串,不进行变量替换,而"定义的字符串会替换变量值。此外,bash中支持函数,例如mcd()函数可以创建目录并进入其中。命令行参数包括$0到$9,$@表示所有参数,$#表示参数个数,$$表示当前脚本的进程识别码,$?表示前一个命令的返回值等。

2023-12-23 14:28:18 308

原创 Course Shell of Missing Semester(一)

这些操作涵盖了Unix shell常见的文件操作和权限管理知识点,对于熟悉Unix/Linux系统的基本操作和shell脚本的编写都有很好的帮助。

2023-12-22 21:42:32 65

原创 MIT 6.S081学习笔记(第八章)

为 xv6 的文件系统添加大文件以及符号链接支持。

2023-12-21 19:22:05 94

原创 xv6 文件系统面临的问题

这篇文章的总结可以强调 **xv6** 文件系统在处理缓存、适配日志大小和管理并发系统调用时所面临的挑战和解决方案,突出了数据一致性和可恢复性的重要性。

2023-12-20 15:47:03 78

原创 实现个人日志命令行工具(C语言)

成功创建了一个能够将命令行输入的日志同步到 GitHub 的工具,并且能够在终端直接使用。这个小工具提供了便捷的日志记录和同步功能,是一个不错的编程趣味项目!

2023-12-19 16:43:26 129

原创 xv6 文件系统(下)

这种技术在许多数据系统中也被广泛应用,比如数据库系统(比如MySQL、PostgreSQL等)、缓存系统(比如Redis)等。它们使用日志记录来确保数据库或者缓存在崩溃或者异常情况下的数据完整性和一致性。通过记录操作和事务,系统可以在崩溃后重新应用这些记录,从而确保数据的恢复和一致性。

2023-12-18 22:43:42 78

原创 xv6 文件系统(上)

探讨了文件系统在 xv6 环境下的工作原理,分层次地介绍了文件系统的实现概述、硬盘使用、inode 结构、目录、以及文件系统的工作示例。文章详细解释了inode和block在磁盘上的分布方式,以及文件的创建、写入和元数据修改的过程。它提供了清晰的代码示例和相关函数的解释,为理解文件系统的内部机制提供了深入而全面的认识。

2023-12-18 17:00:59 191

原创 MIT 6.S081学习笔记(第七章)

只有第一个线程进入并执行了驱逐和重新分配后释放了 eviction_lock,blockno 的缓存才从不存在转变为存在。后续命中相同 blockno 的线程会被第二次“blockno 缓存是否存在”的检查拦截,并直接返回已分配的缓存 buf,而不会重新执行驱逐和重新分配。

2023-12-13 23:37:58 104

原创 xv6 中的一些系统调用(下)

这篇文章详细地介绍了 xv6 操作系统中的 sleep() 和 wakeup() 系统调用的实现原理以及相关的内部工作机制。主要强调了在 sleep() 中的原子操作性,确保了操作的完整性,以及在 wakeup() 中唤醒休眠进程的方式。

2023-12-11 14:47:30 79

空空如也

空空如也

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

TA关注的人

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