当前位置: 首页 > news >正文

Linux namespace

前言

从《initrd&init进程》可知,我们通过ssh连接linux服务器,其实主是linux启动一shell进程与我们做交互。而Linux又是多租户的,这使用得用户与用户间产生了,资源的争抢。 如何隔离资源,且让用户都无法察觉?

Linux Namespace 是什么

Namespace 是 Linux 内核中实现的特性,本质上是一种资源隔离方案.
其提供了一种抽象机制,将原本全局共享的资源隔离成不同的集合,集合中的成员独享其原本全局共享的资源。

举个例子:进程 A 和进程 B 分别属于两个不同的 Namespace,那么进程 A 将可以使用 Linux 内核提供的所有 Namespace 资源:如独立的主机名,独立的文件系统,独立的进程编号等等。同样地,进程 B 也可以使用同类资源,但其资源与进程 A 使用的资源相互隔离,彼此无法感知。
在这里插入图片描述
从用户的角度来看,每一个命名空间应该像一台单独的 Linux计算机一样,有自己的 init进程 (PID为 I),其他进程的PID依次递增, A和B空间都有PID为l的init进程, 子命名空间的进程映 射到父命名空间的进程上,父命名空间可以知道每一个子命名空间的运行状态,而子命名空间 与子命名空间之间是隔离的

当前 Linux一共实现了 7 种不同类型的 Namespace
在这里插入图片描述

User Namespace

User namespace 用于隔离安全相关的资源,包括 user IDs and group IDs(keys和 capabilities)。同样一个用户的 user ID 和 group ID 在不同的 user namespace 中可以不一样权限。换句话说,一个用户可以在一个 user namespace 中是普通用户,但在另一个 user namespace 中是超级用户。

打开两个终端

## 终端1## 使用unshare命令进行 namespace
unshare --user /bin/bash## 使用id命令查看
> id
uid=65534(nobody) gid=65534(nogroups) groups=65534(nogroup)## 在新的 user namespace 中,当前用户变成了 nobody,并且 ID 也变成了 65534。
## 这是因为我们还没有映射父 user namespace 的 user ID 和 group ID 到子 user namespace 中来
## 如果没有映射,当在新的 user namespace 中用 getuid() 和 getgid() 获取 user ID 和 group ID 时,系统将返回文件 /proc/sys/kernel/overflowuid 中定义的 user ID 以及 proc/sys/kernel/overflowgid 中定义的 group ID,它们的默认值都是 65534。也就是说如果没有指定映射关系的话,会默认会把 ID 映射到 65534。> cat /proc/sys/kernel/overflowuid
65534
> cat /proc/sys/kernel/overflowgid
65534## 下面我们来完成 nick (外部用户)在新的 user namespace 中的映射。
## 映射ID的方法就是添加映射信息到 /proc/PID/uid_map 和 /proc/PID/gid_map (这里的 PID 是新 user namespace 中的进程 ID,刚开始时这两个文件都是空的)文件中。## 查询当前namespace进程id 
> echo $$
16471## 终端2## 使用ll命令查询,uid_map,gid_map文件的归属
> ll /proc/16471/uid_map /proc/16471/gid_map## 查看容器外用户ID
> id
uid=1000(nick) gid=1000(nick) groups=1000(nick)## 对 uid_map 和 gid_map 文件的写入操作有着严格的权限控制,简单点说就是:这两个文件的拥有者是创建新的 user namespace 的用户
## 所以和这个用户在一个 user namespace 中的 root 账号可以写;这个用户自己是否有写 map 文件的权限还要看它有没有 CAP_SETUID 和 CAP_SETGID 的 capability(权限)## 给nick 用户设置权限
> sudo setcap cap_setgid,cap_setuid+ep /bin/bash
> exec bash## 查询权限
> getcap /bin/bash
/bin/bash = cap_setgid,cap_setuid+ep## uid_map 和 gid_map 的配置信息的格式如下(每个文件中可以有多条配置信息):
## ID-inside-ns(容器内用户ID) ID-outside-ns(容器外用户ID) length
## 比如 0 1000 500 这条配置就表示父 user namespace 中的 1000~1500 映射到新 user namespace 中的 0~500。、
## 容器内 0 为root 对应容器外 1000 (nike用户)> echo '0 1000 500' > /proc/16471/uid_map
> echo '0 1000 500' > /proc/16471/gid_map## 终端1> exec bash
> id
uid=0(root) gid=0(root) groups=65534(nogroup)## 查看root目录仍没有权限,比如这里 root 对应父 user namespace 的用户是 nick
> ll / grep root
dxwx---- 4 nobody nogroup 4096  root/

当然也可以使用“-r” 来将当前用户自动映射root

unshare --user -r /bin/bash

或者在使用其它namespace时,使用sudo命令,直接将root映射到root

sudo unshare -m

命令解释

  • $$ :Shell本身的PID(ProcessID),即当前进程的PID。
  • setcap 设置进程特权的Linux命令。它允许普通用户运行某些需要特权的服务,而无需以root身份运行整个服务
  • uid(用户ID)、gid(初始组ID), groups是用户所在组(这里既可以看到初始组,如果有附加组,则也能看到附加组)

User namespace 与其它 namespace 的关系
. Linux 下的每个 namespace,都有一个 user namespace 与之关联,这个 user namespace 就是创建相应 namespace 时进程所属的 user namespace,相当于每个 namespace 都有一个 owner(user namespace),这样保证对任何 namespace 的操作都受到 user namespace 权限的控制。

NetWork Namespace

Network Namespace 是用来隔离网络设备、 IP地址端口 等网络械的 Namespace。 Network Namespace 可以让每个容器拥有自己独立的(虚拟的)网络设备,而且容器内的应用可以绑定 到自己的端口,每个 Namespace 内的端口都不会互相冲突。在宿主机上搭建网桥后,就能很方 便地实现容器之间的通信,而且不同容器上的应用可以使用相同的端口 。

同样的打开两个终端

## 终端1## 查看ip
> ifconfig
ens33: 192.168.3.34
lo: 127.0.0.1## 使用 root映射的身份进入,并net 隔离
> unshare --net --user -r /bin/bash## 再次查询,发现为空,net 隔离成功
> ifconfig## 查看进程
> echo $$
16894## 终端2## Linux上创建一对veth设备
> sudo ip link add veth0 type veth peer name veth1
> ip a | grep veth
3: veth1@veth0: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 1000
4: veth0@veth1: <BROADCAST,MULTICAST,M-DOWN> mtu 1500 qdisc noop state DOWN group default qlen 100## 为veth0设置IP地址并启动
> sudo ip a add dev veth0 192.168.10.10/24
> sudo ip link set veth0 up
> ifconfig
ens33: 192.168.3.34
lo: 127.0.0.1
veth0: 192.168.10.10## 将veth1移动到刚才新建的network namespace 中
sudo ip link set veth1 netns 16894## 终端1## 在ns1中启动veth1并设置IP地址
> ip link set dev veth1 up
> ip a add dev veth1 192.168.10.20/24
> ifcofing
veth1: 192.168.10.20## 使用ping测试连通
> ping 192.168.10.10
PING 192.168.10.10 (192.168.10.10) 56(84) bytes of data.
64 bytes from 192.168.10.10: icmp_seq=1 ttl=64 time=0.076 ms

现在ns1还不能和公网通信。解决这个问题也很简单,在root network namespace中开启转发并设置SNAT,在ns1中添加默认路由即可。

  • veth是一种Linux内核网络设备,它通常用于在不同的网络命名空间之间创建虚拟网络接口。veth可以分为成对出现的两个设备,一个位于主机上,另一个则与容器相关联。
    在容器技术中,veth设备通常用于将主机上的网络连接和容器内部的网络连接隔离开来。
  • SNAT(Source Network Address Translation)是一种将源IP地址和端口从一个网络地址转换为另一个网络地址的技术

UTS Namespace

uts(UNIX Time-Sharing System) namespace可隔离hostname(主机名)和NIS Domain name(域名,例如cn,edu)资源,使得一个宿主机可拥有多个主机名或Domain Name。换句话说,可让不同namespace中的进程看到不同的主机名.

同样的打开两个终端

## 终端1## 使用 root映射的身份进入,并uts 隔离
> unshare --uts --user -r /bin/bash## 查看hostname
> hostname
ubuntu## 修改hostname 并重新加载shell
> hostname ns1
> exec /bin/bash> hostname
ns1# namespace中修改的主机名不会直接修改主机名配置文件(如/etc/hostname),而是修改内核属性/proc/sys/kernel/hostname:> cat /etc/hostname
ubuntu
> cat /proc/sys/kernel/hostname
ns1## 终端2> cat /proc/sys/kernel/hostname
ubuntu

在这里插入图片描述

Mount Namespace

Mount namespace 为进程提供独立的文件系统视图。简单点说就是,mount namespace 用来隔离文件系统的挂载点,这样进程就只能看到自己的 mount namespace 中的文件系统挂载点。
进程的 mount namespace 中的挂载点信息可以在 /proc/[pid]/mounts、/proc/[pid]/mountinfo 和 /proc/[pid]/mountstats 这三个文件中找到。

同样的打开两个终端

## 终端1## 制作 iso 文件
> mkdir demo 
> cd demo
> mkdir -p iso1/subdir1
> mkdir -p iso2/subdir2
> mkisofs -o 1.iso ./iso1
> mkisofs -o 2.iso ./iso2## 准备2个挂载点
>sudo mkdir /mnt/iso1 /mnt/iso2## 挂载
>sudo mount 1.iso /mnt/iso1## 查看挂载情况
> mount | grep 1.iso
/home/sa/demo/1.iso on /mnt/iso1 type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048,iocharset=utf8)## 终端2## 以root身分进入ns
> sudo unshare -m## 查看挂载情况, 发现挂载情况一样
> mount | grep iso
/home/sa/demo/1.iso on /mnt/iso1 type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048,iocharset=utf8)## 挂载2,卸载1
> mount 2.iso /mnt/iso2
> umount /mnt/iso1## 查看挂载情况, 发现变了
> mount | grep iso
/home/sa/demo/2.iso on /mnt/iso1 type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048,iocharset=utf8)## 终端1## 与终端2不一样了
> mount | grep iso
/home/sa/demo/1.iso on /mnt/iso1 type iso9660 (ro,relatime,nojoliet,check=s,map=n,blocksize=2048,iocharset=utf8)

Mount namespace 实现了挂载点的隔离,但对于某些应用场景,会让我们用起来很不爽。比如系统新添加了一个磁盘设备,我们打算让所有的 mount namespace 都挂载它。过去的做法只能是在每个 mount namespace 中都挂载一遍,很显然,这太不方便了。于是在 Linux 内核 2.6.15 引入了 shared subtree 的概念来解决这个问题。Shared subtree 的核心是允许在 mount namespace 之间自动地或者是受控地传播 mount 和 umount 事件。

PID Namespace

PID namespace 用来隔离进程的 PID 空间,使得不同 PID namespace 里的进程 PID 可以重复且互不影响。PID namesapce 对容器类应用特别重要, 可以实现容器内进程的暂停/恢复等功能,还可以支持容器在跨主机的迁移前后保持内部进程的 PID 不发生变化。

Linux下的每个进程都有一个对应的 /proc/PID 目录,该目录包含了大量的有关当前进程的信息。 对一个 PID namespace 而言,/proc 目录只包含当前 namespace 和它所有子孙后代 namespace 里的进程的信息。创建一个新的 PID namespace 后,如果想让子进程中的 top、ps 等依赖 /proc 文件系统的命令工作,还需要挂载 /proc 文件系统。

## 终端1## 进入ns, 有pid的一定要加--fork
> sudo unshare --pid --mount --fork ## 查看进程ID
> echo $$
1## 使用ps查看进程信息,依旧是原始pid编号,不是1
> psPID TTY          TIME CMD2475 pts/1    00:00:00 sudo2476 pts/1    00:00:00 unshare2477 pts/1    00:00:00 bash2492 pts/1    00:00:00 ps## 使用mount 挂载/proc,并查看
> mount -t proc proc /proc
> psPID TTY          TIME CMD1 pts/1    00:00:00 bash12 pts/1    00:00:00 ps## 其实 unshare 命令提供了一个专门的选项 --mount-proc 来配合 PID namespce 的创建
> sudo unshare --pid --mount-proc --fork 

PID namespace 可以嵌套,也就是说有父子关系,除了系统初始化时创建的根 PID namespace 之外,其它的 PID namespace 都有一个父 PID namespace。一个 PID namespace 的父是指:通过 clone 或 unshare 方法创建 PID namespace 的进程所在的 PID namespace。

在当前 namespace 里面创建的所有新的 namespace 都是当前 namespace 的子 namespace。父 namespace 里面可以看到所有子孙后代 namespace 里的进程信息,而子 namespace 里看不到祖先或者兄弟 namespace 里的进程信息。一个进程在 PID namespace 的嵌套结构中的每一个可以被看到的层中都有一个 PID。

## 终端1## 查看当前进程
> echo $$
2351## 连续创建3个子进程
> sudo unshare --pid --mount-proc --fork
> sudo unshare --pid --mount-proc --fork
> sudo unshare --pid --mount-proc --fork## 终端2## 用pstree查看进程树
> pstree -p 2351
bash(2351)
───sudo(2727)───unshare(2728)───bash(2729)
───sudo(2737)───unshare(2738)───bash(2739)
───sudo(2749)───unshare(2750)───bash(2751)## 通过 /proc/[pid]/status 看看 2751 号进程在不同 PID namespace 中的 PID
> grep pid /proc/2751/status
NSpid:	2751	21	11	1## 作用enter命令进入
> sudo nsenter --mount --pid -t 2739 /bin/bash
> pstree -p
bash(1)
───sudo(9)───unshare(10)───bash(11)

PID namespace 中的 init 进程
在一个新的 PID namespace 中创建的第一个进程的 PID 为 1,该进程被称为这个 PID namespace 中的 init 进程。

  • 在 Linux 系统中,进程的 PID 从 1 开始往后不断增加,并且不能重复(当然进程退出后,PID 会被回收再利用),进程的 PID 为 1 的进程是内核启动的第一个应用层进程,被称为 init 进程(不同的 init 系统的进程名称可能不太一样)。这个进程具有特殊意义,当 init 进程退出时,系统也将退出。所以除了在 init 进程里指定了 handler 的信号外,内核会帮 init 进程屏蔽掉其他任何信号,这样可以防止其他进程不小心 kill 掉 init 进程导致系统挂掉。
  • 不过有了 PID namespace 后,可以通过在父 PID namespace 中发送 SIGKILL 或者 SIGSTOP 信号来终止子 PID namespace 中的 PID 为 1 的进程。由于 PID 为 1 的进程的特殊性,当这个进程停止后,内核将会给这个 PID namespace 里的所有其他进程发送 SIGKILL 信号,致使其他所有进程都停止,最终 PID namespace 被销毁掉。
  • 当一个进程的父进程退出后,该进程就变成了孤儿进程。孤儿进程会被当前 PID namespace 中 PID 为 1 的进程接管,而不是被最外层的系统级别的 init 进程接管。

主要参考

《linux unshare 命令,详解Linux Namespace之User》
《Linux namespace之:network namespace》
《Linux Namespace : Mount》
《Linux Namespace : PID 》
《Linux Namespace : IPC 》

相关文章:

Linux namespace

​ 前言 从《initrd&init进程》可知&#xff0c;我们通过ssh连接linux服务器&#xff0c;其实主是linux启动一shell进程与我们做交互。而Linux又是多租户的&#xff0c;这使用得用户与用户间产生了&#xff0c;资源的争抢。 如何隔离资源&#xff0c;且让用户都无法察觉&…...

第十三章 移动和旋转(上)

移动和旋转是游戏对象最频繁地操作。我们上个章节简单介绍了Cube的移动和旋转。移动是修改transform的position属性&#xff0c;旋转是修改transform的eulerAngles&#xff08;欧拉角&#xff09;属性&#xff0c;两者属性值均可以使用Vector3向量来实现。需要大家注意的是&…...

视频文件切片

1.为什么网络点播系统使用m3u8更有优势?为何点播要用M3U8来搞&#xff1f;存成一个文件不更好吗&#xff1f; 一个MP4文件可能几百M或几个G&#xff0c;如果读取整个MP4文件的信息并且需要下载一段内容&#xff0c;首次打开播放超慢&#xff08;加载时间长&#xff09;。如果把…...

维生素的缺乏与生理功能,是否需要补充维生素【持续学习】

health & nutrition 学习自河南大学丁勇老师&#xff1a;https://space.bilibili.com/510028707 去医院查体内维生素缺啥&#xff1a;营养科或内科开单子 直接门诊查个维生素就可以。9项不到600块 正常吃饭&#xff0c;保湿和防晒 伤口愈合慢——蛋白质&#xff0c;vc 干燥…...

CUDA下载,以及下载GPU版本的pytorch

一、下载anaconda 因为这步我之前就下好了&#xff0c;主要参考这个链接&#xff1a;史上最全最详细的Anaconda安装教程 二、下载CUDA 1.首先观察自己需要什么版本的CUDA&#xff0c;以及是否安装过CUDA 先cmd&#xff0c;输入命令 nvidia-smi结果如下&#xff0c;所以我们…...

学习笔记:c存储类

✨博文作者&#xff1a;烟雨孤舟 &#x1f496; 喜欢的可以 点赞 收藏 关注哦~~ ✍️ 作者简介: 一个热爱大数据的学习者 文章目录 目录 文章目录 简介 auto 存储类 register 存储类 static 存储类 extern 存储类 总结 简介 存储类定义 C 程序中变量/函数的的存储位置…...

236. 二叉树的最近公共祖先【190】

难度等级&#xff1a;中等 上一篇算法&#xff1a; 103. 二叉树的锯齿形层序遍历【191】 力扣此题地址&#xff1a; 236. 二叉树的最近公共祖先 - 力扣&#xff08;Leetcode&#xff09; 1.题目&#xff1a;236. 二叉树的最近公共祖先 给定一个二叉树, 找到该树中两个指定节点…...

即时配送,即时很重要!商家能不能盈利,“快”是源头

“家里水果没有了&#xff0c;选几样叫个跑腿送来吧。” “现在得囤点布洛芬了&#xff0c;我从网上下单。” “同城配送真是太及时、太方便了。” 最近一段时间&#xff0c;如果要问有什么产业突然兴起的话&#xff0c;即时零售无疑是市场最受欢迎的产业。甚至有种说法&…...

ChatGPT原理剖析

文章目录 ChatGPT常见误解1. 罐头回应2. 网络搜寻重组 ChatGPT真正做的事——文字接龙ChatGPT背后的关键技术——预训练&#xff08;Pre-train&#xff09;一般机器是怎样学习的&#xff1f; ChatGPT带来的研究问题1. 如何精准提出需求2. 如何更改错误3. 侦测AI生成的物件4. 不…...

「C/C++」C/C++软件跨平台思维

博客主页&#xff1a;何曾参静谧的博客 文章专栏&#xff1a;「C/C」C/C学习 目录 相关术语一、编写可移植的代码&#xff1a;二、使用跨平台的C库和框架&#xff1a;三、进行兼容性测试&#xff1a;四、用户界面设计&#xff1a; 相关术语 跨平台思维&#xff1a;是指在软件开…...

c# 通过界面上填写的信息输出到对应的word中,并另存为一个新的文件

c# 通过界面上填写的信息输出到对应的word中&#xff0c;并另存为一个新的文件 using System; using System.Collections.Generic; using System.ComponentModel; using System.Data; using System.Drawing; using System.Linq; using System.Text; using System.Threading.Tas…...

HTML+CSS+JS 学习笔记(四)———jQuery

&#x1f331;博客主页&#xff1a;大寄一场. &#x1f331;系列专栏&#xff1a;前端 &#x1f331;往期回顾&#xff1a; &#x1f618;博客制作不易欢迎各位&#x1f44d;点赞⭐收藏➕关注​​ 目录 jQuery 基础 jQuery 概述 下载与配置jQuery 2. 配置jQuery jQuery 选…...

TryHackMe-Mnemonic(boot2root)

Mnemonic I hope you have fun. 端口扫描 循例nmap FTP枚举 尝试anonymous Web枚举 进80 gobuster扫 对着webmasters再扫一下 对着backups继续扫 下载zip文件&#xff0c;发现有密码 zip2john john直接爆 查看note.txt, 给出了ftpuser hydra直接爆ftp 进到ftp 用wget下载所…...

Nacos注册中心的使用

文章目录 Nacos注册中心1. 服务注册到nacos1&#xff09;引入依赖2&#xff09;配置nacos地址3&#xff09;重启 2.服务分级存储模型2.1.给user-service配置集群2.2.同集群优先的负载均衡 3.权重配置 Nacos注册中心 国内公司一般都推崇阿里巴巴的技术&#xff0c;比如注册中心…...

项目中别用 “! = null“ 做判空了

问题 为了避免空指针调用&#xff0c;我们经常会看到这样的语句: if (someobject ! null) {someobject.doCalc();}最终&#xff0c;项目中会存在大量判空代码&#xff0c;丑陋繁杂。。。如何避免这种情况&#xff1f;是否滥用了判空&#xff1f; 最终&#xff0c;项目中会存在…...

MySQL数据库——MySQL子查询

子查询是 MySQL 中比较常用的查询方法&#xff0c;通过子查询可以实现多表查询。子查询指将一个查询语句嵌套在另一个查询语句中。子查询可以在 SELECT、UPDATE 和 DELETE 语句中使用&#xff0c;而且可以进行多层嵌套。在实际开发时&#xff0c;子查询经常出现在 WHERE 子句中…...

工具链和其他-超级好用的web调试工具whistle

目录 whistle介绍 整体结构 能力 规则 6个使用场景示例 1.修改Host 2.代理 3.替换文件&#xff08;线上报错时&#xff09; 4.替换UA 5.远程调试 6.JS注入 互动 whistle介绍 整体结构 安装&#xff1a; npm install whistle -g cli&#xff1a;whistle help 启动…...

ROS第四十三节——定位

https://download.csdn.net/download/qq_45685327/87725276 1.新建launch文件 关于launch文件的实现&#xff0c;在amcl功能包下的example目录已经给出了示例&#xff0c;可以作为参考&#xff0c;具体实现: roscd amcl ls examples gedit amcl_diff.launch 该目录下会列出两…...

2023年第二十届五一数学建模竞赛题目 C题详细思路

详细思路以及发布视频版&#xff0c;大家可以去观看&#xff0c;这里是对应的文字版&#xff0c;内容相差不多。 C题&#xff1a;“双碳”目标下低碳建筑研究 C题的问题设置其实是本次比赛最简单的一道&#xff0c;就是简单的综合评价预测模型。真正提升C题难度的其实是C题的…...

模块化编程原理示意图--CommonJS 模块编程--ES6 模块编程思路分析/图解--三种导出形式--全部代码示例

目录 模块化编程 基本介绍 模块化编程原理示意图 模块化编程分类 CommonJS 模块编程 介绍 应用实例 1. 需求说明 2. 思路分析/图解 3. 代码实现 function.js use.html use.js ES6 模块编程 介绍 需求说明 思路分析/图解 代码实现 common.js use_common.js …...

Ansys Zemax | 如何模拟双折射偏振器件

这篇文章介绍了什么是双折射现象、如何在OpticStudio中模拟双折射 (birefringence)、如何模拟双晶体的双折射偏振器以及如何计算偏振器的消光比。&#xff08;联系我们获取文章附件&#xff09; 什么是双折射现象 一般的光学材料都是均匀的各向同性的&#xff0c;也就是说无论光…...

Java关键字之:this

一、this关键字的使用 1、this可以用来修饰、调用&#xff1a;属性、方法、构造器 2、this修饰属性和方法 this理解为&#xff1a;当前对象 或 当前正在创建的对象 在类的方法中。我们可以使用“this.属性"或”this.方法“的方式。调用当前对象属性或者方法。但是&#…...

嵌入式Linux驱动开发(九)Linux中断

1. Linux中断简介 1&#xff09;中断号 linux内核中使用一个int变量表示中断号。 2&#xff09;申请中断&#xff1a; 该函数可以自动激活中断&#xff0c;但是可能引起睡眠&#xff0c;所以需要小心使用。 int request_irq(unsigned int irq, //要申请中断的中断号irq_ha…...

数据库系统-并发控制

文章目录 一、为什么要并发控制1.2 并发控制解决的问题1.2.1 脏读1.2.2 幻读1.2.3 不可重复读1.2.4 数据丢失问题 二、事务调度及可串行性2.1 事务2.1.1 事务的宏观2.1.2 事务的微观2.1.3 事务的特性 ACID 2.2 事务调度与可串行性2.3 冲突可串行化判定 三、基于封锁的并发控制方…...

Java8 教程_编程入门自学教程_菜鸟教程-免费教程分享

教程简介 Java 8 (又称为 jdk 1.8) 是 Java 语言开发的一个主要版本。 Java 8 是oracle公司于2014年3月发布&#xff0c;可以看成是自Java 5 以来最具革命性的版本。Java 8为Java语言、编译器、类库、开发工具与JVM带来了大量新特性。 Java 8入门教程 - 从简单的步骤了解Java…...

从零开始学架构——高可用存储架构

双机架构 存储高可用方案的本质都是通过将数据复制到多个存储设备&#xff0c;通过数据冗余的方式来实现高可用&#xff0c;其复杂性主要体现在如何应对复制延迟和中断导致的数据不一致问题。因此&#xff0c;对任何一个高可用存储方案&#xff0c;我们需要从以下几个方面去进…...

连ChatGPT都不懂的五一调休,到底怎么来的?

今天是周几&#xff1f; 你上了几天班了&#xff1f; 还要上几天班放假&#xff1f; 五一啥安排&#xff1f; 出行的票抢到了吗&#xff1f; 调休到底是谁发明的&#xff1f;&#xff01; 五一劳动节是要劳动吗&#xff1f; 为什么昨天是周一&#xff0c;今天还是周一&a…...

AES工作流程

工作流程 模式 1&#xff1a;加密 ⚫ 复位EN 重置AES模块 ⚫ 设置模式寄存器mode[1:0]00&#xff0c;设置流数据处理模式寄存器CHMOD[1:0] ⚫ 写AES_KEYRx寄存器&#xff0c;CTR和CBC模式下写AES_IVRx寄存器 ⚫ 写EN1&#xff0c;使能AES ⚫ 写AES_DINR 寄存器4次 ⚫ 等待CCF标…...

C++11

C11 统一的列表初始化 在介绍这里的列表初始化之前&#xff0c;首先我认为这是一个比较鸡肋的功能特性&#xff0c;而且使用起来会和之前C98时有些区别。 // 首先可以定义普通的内置类型的变量int x1 1;int x2 { 1 };int x3{ 1 }; // 这样看起来着实有些怪int arry1[] { 1,…...

ubuntu18.04 配置zlmediakit 支持ffmpeg转码记录

1、zlmediakt 默认不支持ffmepg转码&#xff0c;需要在根目录下的CamkeLists.txt里面option(ENABLE_FFMPEG "Enable FFmpeg" OFF) 将OFF改成ON, 删除原有的build目录&#xff0c;sudo mkdir build. cd build,cmake .. 这样在编译生成文件夹release/linux/debug/生…...