博客重载记录
博客重载记录
- 流控算法实现
- open系统调用流程
- 二分查找
前言: 有时候看了一些比较好的文章,过几天就忘了,想想不如自己实现一遍博客代码或按博客结构自己写一遍,加深印象,但把别人的内容改个名字变成自己的博客,有点不太好,故全写在这个博客中,权当个人记录。
流控算法实现
参考文章:流量控制-从原理到实现
open系统调用流程
参考文章:走马观花: Linux 系统调用 open 七日游(一)
linux系统调用简要介绍
操作系统为在用户态运行的进程与硬件设备进行交互提供了一组接口。在应用程序与硬件设置一个额外层具有很多优点。首先这使得编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来;其次,这极大地提升了系统的安全性,因为内核在试图满足某个请求之前在接口级就可以检查这种请求的正确性;最后,更重要的是这些接口使得程序更具有移植性,因为只要内核所提供的一组接口相同,那么在任一内核之上就可以正确地编译和执行程序。Unix系统通过向内核发出系统调用(system call)实现了用户态进程和硬件设备之间的大部分接口。
《深入理解linux内核》——系统调用
【纯干货】linux内核——系统调用原理及实现
一次系统调用的完整执行过程如下:
- 通过特定指令发出系统调用(int $0x80、sysenter、syscall)
- CPU从用户态切换到内核态,进行一些寄存器和环境设置
- 调用system_call内核函数,通过系统调用号获取对应的服务例程
- 调用系统调用处理例程
- 使用特定指令从系统调用返回用户态(iret、sysexit、sysret)
系统调用号定义:
# arch/x86/entry/syscalls/syscall_64.tbl
#
# 64-bit system call numbers and entry vectors
#
# The format is:
# <number> <abi> <name> <entry point>
#
# The __x64_sys_*() stubs are created on-the-fly for sys_*() system calls
#
# The abi is "common", "64" or "x32" for this file.
#
0 common read __x64_sys_read
1 common write __x64_sys_write
2 common open __x64_sys_open
3 common close __x64_sys_close
4 common stat __x64_sys_newstat
5 common fstat __x64_sys_newfstat
6 common lstat __x64_sys_newlstat
7 common poll __x64_sys_poll
8 common lseek __x64_sys_lseek
9 common mmap __x64_sys_mmap
10 common mprotect __x64_sys_mprotect
11 common munmap __x64_sys_munmap
12 common brk __x64_sys_brk
13 64 rt_sigaction __x64_sys_rt_sigaction
14 common rt_sigprocmask __x64_sys_rt_sigprocmask
系统调用分派表(dispatch table) sys_call_table:
// arch/x86/entry/syscall_64.c
// SPDX-License-Identifier: GPL-2.0
/* System call table for x86-64. */#include <linux/linkage.h>
#include <linux/sys.h>
#include <linux/cache.h>
#include <asm/asm-offsets.h>
#include <asm/syscall.h>/* this is a lie, but it does not hurt as sys_ni_syscall just returns -EINVAL */
extern asmlinkage long sys_ni_syscall(const struct pt_regs *);
#define __SYSCALL_64(nr, sym, qual) extern asmlinkage long sym(const struct pt_regs *);
#include <asm/syscalls_64.h>
#undef __SYSCALL_64#define __SYSCALL_64(nr, sym, qual) [nr] = sym,asmlinkage const sys_call_ptr_t sys_call_table[__NR_syscall_max+1] = {/** Smells like a compiler bug -- it doesn't work* when the & below is removed.*/[0 ... __NR_syscall_max] = &sys_ni_syscall,
#include <asm/syscalls_64.h>
};// 相关定义
#ifdef CONFIG_X86_64
typedef asmlinkage long (*sys_call_ptr_t)(const struct pt_regs *);
#else
typedef asmlinkage long (*sys_call_ptr_t)(unsigned long, unsigned long,unsigned long, unsigned long,unsigned long, unsigned long);/** Non-implemented system calls get redirected here.*/
asmlinkage long sys_ni_syscall(void)
{return -ENOSYS;
}
系统调用最多6个额外参数(除系统调用号)
sys_open声明与定义
linux Kernel代码艺术——系统调用宏定义
// 函数声明
asmlinkage long sys_open(const char __user *filename, int flags, umode_t mode);
// 函数定义
SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
{if (force_o_largefile())flags |= O_LARGEFILE;return do_sys_open(AT_FDCWD, filename, flags, mode);
}
SYSCALL_DEFINE3作用
#define SYSCALL_DEFINE1(name, ...) SYSCALL_DEFINEx(1, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE2(name, ...) SYSCALL_DEFINEx(2, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE3(name, ...) SYSCALL_DEFINEx(3, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE4(name, ...) SYSCALL_DEFINEx(4, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE5(name, ...) SYSCALL_DEFINEx(5, _##name, __VA_ARGS__)
#define SYSCALL_DEFINE6(name, ...) SYSCALL_DEFINEx(6, _##name, __VA_ARGS__)#define SYSCALL_DEFINE_MAXARGS 6#define SYSCALL_DEFINEx(x, sname, ...) \SYSCALL_METADATA(sname, x, __VA_ARGS__) \__SYSCALL_DEFINEx(x, sname, __VA_ARGS__)SYSCALL_DEFINE3(open, const char __user *, filename, int, flags, umode_t, mode)
宏定义展开之后就成为:
asmlinkage long sys_open(const char __user *filename, int flags, umode_t mode);
宏展开后3表示系统参数个数,使用宏展开是为了将参数都当成long类型,进而执行寄存器的符号位扩展
asmlinkage
asmlinkage指定用堆栈传参数,用意是什么?寄存器不是更快吗
asmlinkage作用就是告诉编译器,函数参数不是用用寄存器来传递,而是用堆栈来传递的;
相关回答:
像楼上各位所说,用户调用syscall的时候,参数都是通过寄存器传进来的。中间内核由把所有的参数压栈了, 所以这个asmlinkage可以通过到gcc,恰好可以用正确的调用方式取到参数。
内核前面的那些统一处理很重要,这样后端真正的的syscall 实现函数就可以得到统一的调用方式了,而不是之间面对不同的abi。确实比较方便了。
不然每个syscall函数里面都要自己去处理不同abi,多很多重复代码。
当然也可以考虑在这个统一的处理的时候,把参数全部按照一定的规范放到寄存器。 但这个方法不能在所有的cpu架构上面都做的到。
我觉得这里的选择,“统一”要比这个“寄存器传参”要重要。 从用户切换到内核,要做大量的处理。相比较其他部分,这点参数的开销实在不算什么。
二分查找
写对二分查找不是套模板并往里面填空,需要仔细分析题意
#include <bits/stdc++.h>
using namespace std;
int BinaryFindEqual(const vector<int>& data, int target) { // 等于// 结果可能出现在[0,n-1]区间,不存在时返回-1int low = 0;int high = data.size() - 1;while (low < high) {int mid = (low + high) / 2; // 靠近low high都可以if (data[mid] == target) {return mid;} else if (data[mid] > target) {high = mid - 1;} else {low = mid + 1;}}// 压缩区间至[low,high], low==highif (data[low] == target) {return low;}return -1;
}int BinaryFindFirstGreaterEqual(const vector<int>& data, int target) { // 第一次大于等于// 结果可能落在[0,n]int low = 0;int high = data.size();while (low < high) {int mid = (low + high) / 2; // 靠近lowif (data[mid] >= target) {high = mid;} else {low = mid + 1;}}// 压缩区间至[low,high], low==highreturn low;
}int BinaryFindFirstGreater(const vector<int>& data, int target) { // 第一次大于// 结果可能落在[0,n]int low = 0;int high = data.size();while (low < high) {int mid = (low + high) / 2; // 靠近lowif (data[mid] > target) {high = mid;} else {low = mid + 1;}}// 压缩区间至[low,high], low==highreturn low;
}int BinaryFindLastLesserEqual(const vector<int>& data, int target) { // 最后一次小于等于// 结果可能落在[-1,n-1]if (data[0] > target) {return -1;}int low = 0;int high = data.size() - 1;while (low < high) {int mid = (low + high + 1) / 2; // 靠近highif (data[mid] > target) {high = mid - 1;} else {low = mid;}}// 压缩区间至[low,high], low==highreturn low;
}int BinaryFindLastLesser(const vector<int>& data, int target) { // 最后一次小于// 结果可能落在[-1,n-1]if (data[0] >= target) {return -1;}int low = 0;int high = data.size() - 1;while (low < high) {int mid = (low + high + 1) / 2; // 靠近highif (data[mid] >= target) {high = mid - 1;} else {low = mid;}}// 压缩区间至[low,high], low==highreturn low;
}int BinaryFindFirstEqual(const vector<int>& data, int target) { // 第一次等于// 结果可能落在[0,n-1],不存在时返回-1int low = 0;int high = data.size() - 1;while (low < high) {int mid = (low + high) / 2; // 靠近lowif (data[mid] > target) {high = mid - 1;} else if (data[mid] < target) {low = mid + 1;} else {high = mid;}}// 压缩区间至[low,high], low==highif (data[low] == target) {return low;}return -1;
}int BinaryFindLastEqual(const vector<int>& data, int target) { // 最后一次等于// 结果可能落在[0,n-1],不存在时返回-1int low = 0;int high = data.size() - 1;while (low < high) {int mid = (low + high + 1) / 2; // 靠近highif (data[mid] > target) {high = mid - 1;} else if (data[mid] < target) {low = mid + 1;} else {low = mid;}}// 压缩区间至[low,high], low==highif (data[low] == target) {return low;}return -1;
}int BinaryFindEqualCompare(const vector<int>& data, int target) { // 返回第一次相等的下标for (int i = 0; i < data.size(); i++) {if (data[i] == target) {return i;}}return -1;
}int BinaryFindFirstGreaterEqualCompare(const vector<int>& data, int target) {for (int i = 0; i < data.size(); i++) {if (data[i] >= target) {return i;}}return data.size();
}int BinaryFindFirstGreaterCompare(const vector<int>& data, int target) {for (int i = 0; i < data.size(); i++) {if (data[i] > target) {return i;}}return data.size();
}int BinaryFindLastLesserEqualCompare(const vector<int>& data, int target) {for (int i = data.size() - 1; i >= 0; i--) {if (data[i] <= target) {return i;}}return -1;
}int BinaryFindLastLesserCompare(const vector<int>& data, int target) {for (int i = data.size() - 1; i >= 0; i--) {if (data[i] < target) {return i;}}return -1;
}int BinaryFindFirstEqualCompare(const vector<int>& data, int target) {for (int i = 0; i < data.size(); i++) {if (data[i] == target) {return i;}}return -1;
}int BinaryFindLastEqualCompare(const vector<int>& data, int target) {for (int i = data.size() - 1; i >= 0; i--) {if (data[i] == target) {return i;}}return -1;
}using FindFunc = function<int(const vector<int>&, int)>;
void TestBinaryFind(const vector<int>& data, const vector<int>& targets, FindFunc test_fn, FindFunc right_fn, string testname) {for (int target : targets) {int res1 = test_fn(data, target);int res2 = right_fn(data, target);if (res1 != res2) {cout << "wrong anwer." << endl;cout << "res1: " << res1 << " res2: " << res2 << endl;}}cout << testname << " complete." << endl;
}int main() {vector<int> unique_data;default_random_engine e;uniform_int_distribution<int> u(1, 100);e.seed(time(0));for (int i = 5; i < 95; i++) {if (u(e) > 50) {unique_data.emplace_back(i);}}vector<int> targets;for (int i = 0; i <= 100; i++) {targets.emplace_back(i);}cout << "unique data test:" << endl;TestBinaryFind(unique_data, targets, BinaryFindEqual, BinaryFindEqualCompare, "BinaryFindEqual");TestBinaryFind(unique_data, targets, BinaryFindFirstGreaterEqual, BinaryFindFirstGreaterEqualCompare, "BinaryFindFirstGreaterEqual");TestBinaryFind(unique_data, targets, BinaryFindFirstGreater, BinaryFindFirstGreaterCompare, "BinaryFindFirstGreater");TestBinaryFind(unique_data, targets, BinaryFindLastLesserEqual, BinaryFindLastLesserEqualCompare, "BinaryFindLastLesserEqual");TestBinaryFind(unique_data, targets, BinaryFindLastLesser, BinaryFindLastLesserCompare, "BinaryFindLastLesser");vector<int> repeat_data;for (int i = 5; i < 95; i++) {while (u(e) > 30) {repeat_data.emplace_back(i);}}cout << "repeat data test:" << endl;TestBinaryFind(repeat_data, targets, BinaryFindFirstGreaterEqual, BinaryFindFirstGreaterEqualCompare, "BinaryFindFirstGreaterEqual");TestBinaryFind(repeat_data, targets, BinaryFindFirstGreater, BinaryFindFirstGreaterCompare, "BinaryFindFirstGreater");TestBinaryFind(repeat_data, targets, BinaryFindLastLesserEqual, BinaryFindLastLesserEqualCompare, "BinaryFindLastLesserEqual");TestBinaryFind(repeat_data, targets, BinaryFindLastLesser, BinaryFindLastLesserCompare, "BinaryFindLastLesser");TestBinaryFind(repeat_data, targets, BinaryFindFirstEqual, BinaryFindFirstEqualCompare, "BinaryFindFirstEqual");TestBinaryFind(repeat_data, targets, BinaryFindLastEqual, BinaryFindLastEqualCompare, "BinaryFindLastEqual");
}
相关文章:
博客重载记录
博客重载记录流控算法实现open系统调用流程二分查找前言: 有时候看了一些比较好的文章,过几天就忘了,想想不如自己实现一遍博客代码或按博客结构自己写一遍,加深印象,但把别人的内容改个名字变成自己的博客,…...
open-cv绘制简单形状line() circle() rectangle() polylines() putText() cvtColor()
OpenCV彩色图像中一个像素是按照“B-G-R”模式组织的。 绘图函数的一些公众参数: img :图像对象 color: 颜色,如果彩色用一个三元组表示,三元组的元素按照B-G-R组织,三元组(0,255,0)中B为0,G为2…...

基于 PyTorch + LSTM 进行时间序列预测(附完整源码)
时间序列数据,顾名思义是一种随时间变化的数据类型。 例如,24小时内的温度、一个月内各种产品的价格、某家公司一年内的股票价格等。深度学习模型如长短期记忆网络(LSTM)能够捕捉时间序列数据中的模式,因此可以用于预…...

GEE页面介绍
目录一、背景二、用户界面三、数据类型:栅格1、请求图像集合2、学习查看栅格元数据3、矢量实例一:四、数据集五、数据属性1、空间分辨率2、时间分辨率六可视化多个波段1、真彩色(TCI)2彩色红外(CI)3、伪色 1 和 2 (FC1/FC2)七、可…...

python自动发送邮件,qq邮箱、网易邮箱自动发送和回复
在python中,我们可以用程序来实现向别人的邮箱自动发送一封邮件,甚至可以定时,如每天8点钟准时给某人发送一封邮件。今天,我们就来学习一下,如何向qq邮箱,网易邮箱等发送邮件。 一、获取邮箱的SMTP授权码。…...
hastcat
hashcat 下载地址: https://hashcat.net/hashcat/ 案例 Usage: hashcat [options]... hash|hashfile|hccapxfile [dictionary|mask|directory]...https://xz.aliyun.com/t/4008破解linux shadow /etc/shadow中密码格式: $id$salt$encrypted如:$1$2eWq10AC$NaQqalCk3 1表…...
242. 一个简单的整数问题
Powered by:NEFU AB-IN Link 文章目录242. 一个简单的整数问题题意思路代码242. 一个简单的整数问题 题意 给定长度为 N的数列 A,然后输入 M行操作指令。 第一类指令形如 C l r d,表示把数列中第 l∼r个数都加 d 第二类指令形如 Q x,表示询问…...

docker安装Redis高可用(一主二从三哨兵)
本次教程使用docker swarm安装 准备三台机器 hostIP用途node1192.168.31.130redis-master01,redis哨兵节点01node2192.168.31.131redis-slave01, redis哨兵节点02node3192.168.31.132redis-slave02 redis哨兵节点02 注意事项: 1:需要保证三…...

安全防御之入侵检测篇
目录 1.什么是IDS? 2.IDS和防火墙有什么不同?3.IDS的工作原理? 4.IDS的主要检测方法有哪些?请详细说明 5.IDS的部署方式有哪些? 6.IDS的签名是什么意思?签名过滤器有什么用?例外签名的配置作…...

学习系统编程No.10【文件描述符】
引言: 北京时间:2023/3/25,昨天摆烂一天,今天再次坐牢7小时,难受尽在不言中,并且对于笔试题,还是非常的困难,可能是我做题不够多,也可能是没有好好的总结之前做过的一些…...

网络基础认识
目录 一、计算机网络背景 1.1 网络发展 1.2 "协议"由来 二、网络协议初识 2.1 协议分层 2.2 OSI七层模型 2.3 TCP/IP五层模型 三、网络协议栈 四、数据包封装与分用 五、网络传输基本流程 5.1 同局域网的两台主机通信 5.2 跨网络的两台主机通信 六、网络…...

【蓝桥杯_练习】
蓝桥杯1.创建工程2.LED灯点亮led.c3.LCD液晶屏显示lcd.c4.定时器按键单机interrupt.hinterrupt.cman.c5.定时器(长按键)interrupt.hinterrupt.cmain.c6.PWMmain.c7.定时器-输入捕获(频率,占空比测量)interrupt.cmain.c…...

【C语言蓝桥杯每日一题】——跑步锻炼
【C语言蓝桥杯每日一题】—— 跑步锻炼😎前言🙌排序🙌总结撒花💞😎博客昵称:博客小梦 😊最喜欢的座右铭:全神贯注的上吧!!! 😊作者简介…...

Qt之实现类似软件安装时的新功能介绍界面
一.效果 在软件安装时,一般会轮播软件的新功能,安装后,如果还想查看这些新功能该怎么办呢,我们可以把这个介绍新新功能的小应用集成到软件的“帮助”菜单中,比起纯黑文字的无趣介绍,图文方式的呈现会生动得多。 最近在看《赘婿》,借几张图过来用用。 二.原理 1.分层结…...
echarts地图不同地区设置不同的颜色
var myChart ec.init(document.getElementById(main));let option {tooltip: {trigger: item,},dataRange: {//左下角的颜色块。start:值域开始值;end:值域结束值;label:图例名称;color:自定义…...

网易云音乐API部署Vercel获取接口过程
前提:部署自己的网易云接口主要用途在于在完成前端的仿网易云播放器的时候,根据自己部署的接口可以用于获取数据。大体流程是通过在github上fork别人的API接口项目,然后在Vercel部署即可获得自己的网易云后端数据接口了,不过根据我…...

Java基础:字符串(String)及常用操作
目录 字符串的声明及创建 字符串的操作 连接字符串(或concat) 获取字符串的长度 length 查找字符串 indexOf 获取字符串某个位置的字符 charAt 查询某个字符串是否存在 contains 截取字符串 substring(一) 截取字符串 su…...

FL Studio 21中文版支持主题随心换,FL Studio 21Mac版新增对苹果M2/1家族芯片原生支持。
FL Studio 21.0.0 官方中文版重磅发布 纯正简体中文支持,更快捷的音频剪辑及素材管理器,多样主题随心换! Mac版新增对苹果M2/1家族芯片原生支持。 更新版本:21.0.0支持语言:简体中文/英语更新时间:2022.12…...

【蓝桥杯集训·周赛】AcWing 第96场周赛
文章目录第一题 AcWing 4876. 完美数一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第二题 AcWing 4877. 最大价值一、题目1、原题链接2、题目描述二、解题报告1、思路分析2、时间复杂度3、代码详解第三题 AcWing 4878. 维护数组一、题目1、原…...

【数据结构】顺序表的深度刨剖析
前言:在上一篇文章中,我们已经对数据结构有了一定了解,我们可以通过优化空间复杂度或者时间复杂度从而提高我们程序运行或存储速率。至此我们就知道了数据结构的重要性,所以今天我们将要了解和学习一种实用的数据结构——线性表。…...
【杂谈】-递归进化:人工智能的自我改进与监管挑战
递归进化:人工智能的自我改进与监管挑战 文章目录 递归进化:人工智能的自我改进与监管挑战1、自我改进型人工智能的崛起2、人工智能如何挑战人类监管?3、确保人工智能受控的策略4、人类在人工智能发展中的角色5、平衡自主性与控制力6、总结与…...
FFmpeg 低延迟同屏方案
引言 在实时互动需求激增的当下,无论是在线教育中的师生同屏演示、远程办公的屏幕共享协作,还是游戏直播的画面实时传输,低延迟同屏已成为保障用户体验的核心指标。FFmpeg 作为一款功能强大的多媒体框架,凭借其灵活的编解码、数据…...
基于数字孪生的水厂可视化平台建设:架构与实践
分享大纲: 1、数字孪生水厂可视化平台建设背景 2、数字孪生水厂可视化平台建设架构 3、数字孪生水厂可视化平台建设成效 近几年,数字孪生水厂的建设开展的如火如荼。作为提升水厂管理效率、优化资源的调度手段,基于数字孪生的水厂可视化平台的…...

CocosCreator 之 JavaScript/TypeScript和Java的相互交互
引擎版本: 3.8.1 语言: JavaScript/TypeScript、C、Java 环境:Window 参考:Java原生反射机制 您好,我是鹤九日! 回顾 在上篇文章中:CocosCreator Android项目接入UnityAds 广告SDK。 我们简单讲…...
Spring Boot面试题精选汇总
🤟致敬读者 🟩感谢阅读🟦笑口常开🟪生日快乐⬛早点睡觉 📘博主相关 🟧博主信息🟨博客首页🟫专栏推荐🟥活动信息 文章目录 Spring Boot面试题精选汇总⚙️ **一、核心概…...
Unit 1 深度强化学习简介
Deep RL Course ——Unit 1 Introduction 从理论和实践层面深入学习深度强化学习。学会使用知名的深度强化学习库,例如 Stable Baselines3、RL Baselines3 Zoo、Sample Factory 和 CleanRL。在独特的环境中训练智能体,比如 SnowballFight、Huggy the Do…...
Pinocchio 库详解及其在足式机器人上的应用
Pinocchio 库详解及其在足式机器人上的应用 Pinocchio (Pinocchio is not only a nose) 是一个开源的 C 库,专门用于快速计算机器人模型的正向运动学、逆向运动学、雅可比矩阵、动力学和动力学导数。它主要关注效率和准确性,并提供了一个通用的框架&…...
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join
纯 Java 项目(非 SpringBoot)集成 Mybatis-Plus 和 Mybatis-Plus-Join 1、依赖1.1、依赖版本1.2、pom.xml 2、代码2.1、SqlSession 构造器2.2、MybatisPlus代码生成器2.3、获取 config.yml 配置2.3.1、config.yml2.3.2、项目配置类 2.4、ftl 模板2.4.1、…...

STM32HAL库USART源代码解析及应用
STM32HAL库USART源代码解析 前言STM32CubeIDE配置串口USART和UART的选择使用模式参数设置GPIO配置DMA配置中断配置硬件流控制使能生成代码解析和使用方法串口初始化__UART_HandleTypeDef结构体浅析HAL库代码实际使用方法使用轮询方式发送使用轮询方式接收使用中断方式发送使用中…...

【 java 虚拟机知识 第一篇 】
目录 1.内存模型 1.1.JVM内存模型的介绍 1.2.堆和栈的区别 1.3.栈的存储细节 1.4.堆的部分 1.5.程序计数器的作用 1.6.方法区的内容 1.7.字符串池 1.8.引用类型 1.9.内存泄漏与内存溢出 1.10.会出现内存溢出的结构 1.内存模型 1.1.JVM内存模型的介绍 内存模型主要分…...