
一.git
1.常用指令
1.git clone 仓库地址
2.git status 查看git仓库的状态
3.git add 文件 将文件传入到仓库的暂存区
4.git commit -m "日志" 正式的提交文件
5.git push 将本地仓库的内容同步到远端
6.在.gitignore中添加文件后缀可以不添加该后缀的文件
7.git pull 同步远端仓库和本地仓库
二.gdb
gdb是Linux中常用的调试软件。
只有当可执行文件为debug版本下才可以进行调试。我们正常使用gcc编译时生成的是release版本。想要变为debug需要在gcc的末尾加一个-g。
| 命令 | 作⽤ | 样例 |
|---|---|---|
| list/l | 显⽰源代码,从上次位置开始,每次列出 10⾏ | list/l 10 |
| list/l 函数名 | 列出指定函数的源代码 | list/l main |
| list/l ⽂件名:⾏号 | 列出指定⽂件的源代码 | list/l mycmd.c:1 |
| r/run | 从程序开始连续执⾏ | run |
| n/next | 单步执⾏,不进⼊函数内部, 逐过程 F10 | next |
| s/step | 单步执⾏,进⼊函数内部, 逐语句 F11 | step |
| break/b [⽂件名:]⾏号 | 在指定⾏号设置断点 | break 10 break test.c:10 |
| break/b 函数名 | 在函数开头设置断点 | break main |
| info break/b | 查看当前所有断点的信息 | info break |
| finish | 执⾏到当前函数返回,然后停⽌ | finish |
| print/p 表达式 | 打印表达式的值 | print start+end |
| p 变量 | 打印指定变量的值 | p x |
| set var 变量=值 | 修改变量的值 | set var i=10 |
| continue/c | 从当前位置开始连续执⾏程序 | continue |
| delete/d breakpoints | 删除所有断点 | delete breakpoints |
| delete/d breakpoints n | 删除序号为n的断点 | delete breakpoints 1 |
| disable breakpoints | 禁⽤所有断点 | disable breakpoints |
| enable breakpoints | 启⽤所有断点 | enable breakpoints |
| info/i breakpoints | 查看当前设置的断点列表 | info breakpoints |
| display 变量名 | 跟踪显⽰指定变量的值(每次停⽌时) | display x |
| undisplay 编号 | 取消对指定编号的变量的跟踪显⽰ | undisplay 1 |
| until X⾏号 | 执⾏到指定⾏号 | until 20 |
| backtrace/bt | 查看当前执⾏栈的各级函数调⽤及参数 | backtrace |
| info/i locals | 查看当前栈帧的局部变量值 | info locals |
| quit | 退出GDB调试器 | quit |
| r/run | 运行程序(遇到断点停止) | r |
三.进程
1.进程的概念
课本概念:程序的⼀个执⾏实例,正在执⾏的程序等
内核观点:担当分配系统资源(CPU时间,内存)的实体。
当前:进程 = 内核数据结构(task_struct) + ⾃⼰的程序代码和数据
进程信息被放在⼀个叫做进程控制块的数据结构中,可以理解为进程属性的集合。
课本上称之为PCB(process control block), Linux 操作系统下的 PCB 是: task_struct
在 Linux 中描述进程的结构体叫做 task_struct 。
task_struct 是 Linux 内核的⼀种数据结构类型,它会被装载到RAM(内存)⾥并且包含着进
程的信息。
2.进程相关的代码
1.查看某文件的进程状态
ps ajx | grep test
在所有进程中搜索包含 "test" 的行
ps ajx | head -1
显示进程的第一行信息
2.getpid:获得该进程的id
3.getppid:获得该进程父进程的id
4.fork:在一个进程中打开一个子进程。
5../code &可以把进程在后台上运行
6.echo $?获得僵尸进程的结果码
7.top可以更改进程的NI值,NI值的范围在[-20,19]
8.exit(数字)在C语言中使用直接结束进程并返回进程码
9.putenv(需要导入的环境变量)
3.进程的运行队列以及切换调度
操作系统在执行进程的时候,并不是单一的执行一个单进程。大部分的电脑为多核单CPU的配置。这时为了能够执行多个进程,CPU就不得不进行并行和并发。
并行: 多个进程在多个CPU下分别,同时进⾏运⾏,这称之为并⾏。
并发:多个进程在⼀个CPU下采⽤进程切换的⽅式,在⼀段时间之内,让多个进程都得以推进,称
之为并发。
那么在执行并发时操作系统是怎么去选择要进行的进程呢?原因是在操作系统中有关于进程·状态的一个结构体,一般来说被称为PCB(task_struct)。
而CPU在进行调度时有一个调度器runqueue。runqueue像一个队列一样连接着多个PCB当一个PCB执行完之后继续去排队一直连续的进行称为并发。
这样的调度方法叫FIFO调度。不过这种调度方法并不能体现出PCB中的优先级,所以在很早之前就被淘汰了。
四.环境变量和本地变量
环境变量(environment variables)⼀般是指在操作系统中⽤来指定操作系统运⾏环境的⼀些参数
如:我们在编写C/C++代码的时候,在链接的时候,从来不知道我们的所链接的动态静态库在哪
⾥,但是照样可以链接成功,⽣成可执⾏程序,原因就是有相关环境变量帮助编译器进⾏查找。
环境变量通常具有某些特殊⽤途,还有在系统当中通常具有全局特性'
- echo $NAME: 显⽰某个环境变量值
- export: 设置⼀个新的环境变量
- env: 显⽰所有环境变量
- unset: 清除环境变量
- set: 显⽰本地定义的shell变量和环境变量
本地变量是shell自己设置的变量以及用户设定的变量。
在命令行输入a=100等指令会将该命令传入本地变量中。
常见的环境变量:
PATH : 指定命令的搜索路径
HOME : 指定⽤⼾的主⼯作⽬录(即⽤⼾登陆到Linux系统中时,默认的⽬录)
SHELL : 当前Shell,它的值通常是/bin/bash。
环境变量是可以被子进程继承下去的,但是本地变量不可以。
1.getenv(环境变量名称)可以获得环境变量
2.environ(一个类型为char**的指针)指向环境变量表的首地址,environ[i]可以一次获得环境变量的值。
基于这一些操作我们可以通过环境变量来让各个进程之间来同步数据。
五.进程地址空间
当我们使用fork()去执行父子进程的时候,当我们打印出一个全局变量的地址时,运行代码我们可以发现他们的全局变量的地址是一样的,但是当全局变量只在子进程中进行改变时。父进程中的全局变量并没有改变。但是我们之前在C语言中学到同一块区间管理的一定是一个数据。那么为什么会不一样呢?

这是因为在进程运行中数据所占用的地址并不是一个物理地址而是虚拟地址(线性地址)

之前在学习C语言和C++时我们会遇到这个图,但是这3并不是一个程序地址。这其实是一个进程地址空间。
其实在test_struct中有一个关于进程地址空间的地址指针指向这个表称为mm_struct当需要调用物理内存时通过进程地址空间来进行申请。
