C++ std::move() 实现详解
本文不介绍 std::move() 的功能与用法,有了解需要可参考 std::move - cppreference.com。
本文主要研究 std::move() 的实现原理,从其定义出发,自顶向下剖析。
1. std::move() 的定义移动函数 std::move() 定义在头文件 <utility> 中。
下面的定义取自 GCC 源码:
123456789/** * @brief Convert a value to an rvalue. * @param __t A thing of arbitrary type. * @return The parameter cast to an rvalue-reference to allow moving it.*/template<typename _Tp> constexpr typename std::remove_reference<_Tp>::type&& move(_Tp&& __t) noexcept { return s ...
C++ 内存模型和原子操作
C++ 新标准引入了不少新特性,其中一项非常重要,它既不是新的语法功能,也不是新的程序库工具,而是新的线程感知的内存模型,却被大多数程序员所忽略。内存模型精确定义了基础构建单元应当如何运转。唯有以内存模型为基石,C++ 提供的并发工具方能可靠的工作。多数程序员之所以会忽略内存模型,是因为我们只需要借助互斥保护数据,并采用条件变量、future、线程闩或线程卡来触发事件信号,就足以将多线程运用自如,结果甚少有人深究底层细节。只有当我们尽力“贴近计算机底层硬件”,内存模型的精确细节的重要作用才会彰显。
不论其他语言如何定位,C++ 都是操作系统级别的编程语言。C++ 标准委员会的一个目标是领 C++ 尽量贴近计算机底层,而不必改用其他更低级的语言,C++ 十分灵活,可满足程序员的许多需求,包括容许他们在必要时“贴近计算机底层硬件”,语言本身不应构成障碍。原子类型(atomic)及其操作应运而生,提供了底层同步操作的功能,其常常只需一两条 CPU 指令即可实现。
1. 内存模型基础内存模型牵涉两个方面:基本结构和并发。基本结构关系到整个程序在内存中的布局。它对并发很重要,尤其是在我们分析 ...
C++ 并发操作的同步
C++ 中并发操作的同步手段主要有三种,按复杂程度从低到高依次为:
std::async;
std::packaged_task;
std::promise。
其中 std::async是函数模板,另外两个为类模板。三者都定义在头文件 <future> 中,且由不可拷贝的 std::future 类型的对象接收事件的结果。
我们逐个介绍上述三种,并在其中顺带演示如何使用 std::future 对象。
1. std::async最简单的方法,std::async 函数接收 1 个可调用对象(通常是函数)以及此调用对象的参数。例如:
12345678910111213#include <iostream>#include <future>int sum(int a, int b) { return a + b;}int main(int, char**) { std::future<int> f = std::async(sum, 3, 4); std::cout << f.g ...
Linux 中查看网络连接信息命令 netstat 的常见用法
1. 命令 netstat 的作用netstat 命令用于打印网络连接、路由表、接口统计、伪装连接和多播成员信息。
因为我本人不是专业搞网络的,我最常用的就是用 netstat 打印网络信息,主要是看看 IP、端口什么的,验证一些程序的网络是否正常等。所以本文要给出的可能也是 netstat 最泛用的几个方法(选项),不管是不是专业搞网络的人应该都在某些场景里会用得上。
本文主要参考自 netstat(8) — Linux manual page 中的查看网络连接部分,其他部分感兴趣可以自己看看。
2. netstat 查看网络连接netstat 查看网络连接信息的命令如下:
1netstat [address_family_options]
其实就是命令 netstat 命令后接地址族选项。默认情况下,netstat 显示打开的套接字列表。如果我们不指定任何地址族,那么将打印所有已配置地址族的活动套接字。
与网络连接信息相关的地址族选项有:
-t --tcp:打印使用 TCP 协议网络连接信息。
-u --udp:打印使用 UDP 协议网络连接信息。
-U --udplite:打印 ...
Linux 中查看进程信息命令 ps 的常见用法
ps 命令用于查看当前进程的快照信息,其功能很多,本文只介绍我个人常用的。完整手册见 ps(1) — Linux manual page。
ps 命令通常需要配合选项使用,如果不加选项的话,只会打印出当前 bash 和 ps 本身的简略进程信息:
1234$ ps PID TTY TIME CMD2057074 pts/0 00:00:00 bash2057151 pts/0 00:00:00 ps
不加选项的 ps 命令通常没什么意义,所以我们需要配合选项使用。
1. 参数的种类与大多程序不同,ps 命令有三种选项种类:
Unix 选项,必须以前缀 - 开始,如 ps -ef。
BSD 选项,必须没有前,如 ps aux。
GNL 长选项,必须以前缀 -- 开始,如 ps --deselect。
不同类型的选项可以自由组合,但使用不当可能会发生冲突。
有一些选项是同义的,功能完全相同,但 ps 的实现中为了兼容性而将这些同义的选项都保留了下来。
由于 ps 选项比较多,本文不打算逐一介绍,而是按场景介绍,讲述每个场景该怎么用(用哪些选项),为什 ...
Unable to load authentication plugin 'caching_sha2_password'
1. 报错信息使用某工具连接 MySQL 服务器时,报错:
1Unable to load authentication plugin 'caching_sha2_password'.
此报错信息翻译过来是说,无法加载身份验证插件 caching_sha2_password。
2. 错误分析此错误的根本原因是:MySQL 在 8 版本后使用了新的身份验证插件 caching_sha2_password,而在 8 以前的身份验证插件是 mysql_native_password。
我这里的 MySQL 版本为 8.0.28,我们可以查看下当前的默认身份验证插件的确是 caching_sha2_password:
1234567mysql> show variables like "default_authentication_plugin";+-------------------------------+-----------------------+| Variable_name | Value ...
配置 NFS 实现 Linux 之间的目录共享
网络文件系统(英语:Network File System,缩写作 NFS)是一种分布式文件系统,力求客户端主机可以访问服务器端文件,并且其过程与访问本地存储时一样,它由Sun Microsystems(已被甲骨文公司收购)开发,于1984年发布。NFS 的实现基于 ONC RPC(一个开放、标准的RFC系统,任何人或组织都可以依据标准实现它)。
本文仅介绍 NFS 最简单的用法:在两台不同的 Linux 机器上共享目录。
而 NFS 那些更复杂的用法基本也都是在此简单用法之上的拓展,深入了解配置,举一反三便能做到。
-
我这里以一个简单地实例的实现,来阐述整个过程:
假设有 A 和 B 两台不同的但可以相互连接的 Linux 服务器(我这里均以 CentOS 系统举例),我们要将 A 服务器上的 /nfs-shared/ 目录共享给 B 服务器。在 B 服务器上,将 A 服务器上共享来的目录,挂载(NFS 是通过挂载的方式来访问共享内容的)到自己 /nfs-shard-from-server/ 目录。完成后,A 服务器访问自己的 /nfs-shared/ 目录,与 B 服务器访问目录 ...
Docker 快速开始与基本用法
本人不是 docker 重度用户,也不是从事运营 docker 或 k8s 相关工作的运维人员。我使用 docker 通常是偶尔试一些东西,避免把服务器环境搞乱;或者是想在一个相对干净的环境中临时编译一个项目等。所以我属于比较轻度的 docker 用户,基本上也就只会用到一些基础功能。本文也不会介绍相对复杂的 Dockerfile 配置。
本文的主要目标是:
从 0 快速启动一个 docker 容器,并使用 ssh 登录该容器。
给出一些 docker 比较常用的操作和容器配置(至少是作为轻度用户的我比较常用的)。
本文使用的 Linux 发行版为 CentOS 8。
另外,docker 的安装和使用默认需要 root 权限,如果你需要在没有权限的用户里使用 docker,请查阅官方文档。
1. 安装 Docker1.1. 卸载旧版本 Docker旧版本的 docker 的包名叫做 docker 或者 docker-engine,我们需要把旧版本的 docker 卸载掉(如果有的话):
12345678sudo yum remove docker \ ...
Linux 一键更换国内软件源
通常我是在自己的 Linux 机器上配置代理的,但是确实也有很多场景配置代理是不容易操作的。
为了能顺利安装一些软件,也只能是换国内软件源咯。
更换国内软件源这件事有大佬编写的脚本我们可以拿来直接用,项目地址是 GitHub 或 Gitee。
基本上各种主流的 Linux 发行版都能用,这里就不多说了,更详细的信息可以看项目地址。这里直接说咋用。
用法非常简单:
12wget https://gitee.com/SuperManito/LinuxMirrors/raw/main/ChangeMirrors.shsudo sh ChangeMirrors.sh
即可进入脚本提供的交互界面,像下面这样:
123456789101112131415161718192021222324252627282930313233343536373839+---------------------------------------------------+| || ================= ...
在 VSCode 中配置使用 CMake 的 Linux C/C++ 开发环境
本文默认你已经有在 VSCode 中配置 Linux C/C++ 开发环境的经验。前置微软官方文档 Gcc on Linux。我们知道,在配置 C/C++ 的常规方法中,VSCode 会在项目目录中生成一个名为 .vscode 的隐藏文件夹,里面放着一些相关的配置 json 文件。其中与 C/C++ 环境开发有关的主要有三个:
task.json:编译器的编译相关配置。例如编译命令、编译参数设置等等。
launch.json:调试相关的配置。例如调试器路径、调试目录配置等。
c_cpp_properties.json:编译器路径和智能提示(Intellisense)设置。例如 C++ 版本、用于智能提示的头文件路径设置等。
而如果使用 CMake 的话,我们就只需要配置 CMakeLists.txt 文件(可能是多个)就可以了。
本文用于在 VSCode 中配置使用 CMake 的 Linux C/C++ 开发环境的快速入门,关于更深入的内容,建议看:
CMake Tools for Visual Studio Code documentation:微软官方出的在 VSCode ...