常用Linux命令
ls:列出当前目录内容
ls -l:详细信息列表
ls -a:包括隐藏文件
cd:更改目录
pwd:显示当前目录路径
mkdir:创建新目录
rmdir:删除空目录
rm:删除文件或目录
rm -r:递归删除目录及其内容
cp:复制文件或目录
mv:移动或重命名文件或目录
touch:创建空文件或更新文件的时间戳
cat:查看文件内容
more:分页查看文件内容
less:分页查看文件内容,支持向上滚动
head -n 10 file_name:查看文件前10行
tail -f file_name:实时查看文件追加的内容
ps:查看当前运行的进程
ps aux:查看所有用户的所有进程
top:实时显示系统资源使用情况
kill process_id:终止进程
df:查看文件系统磁盘空间使用情况
df -h: 以人类可读的格式显示
du:显示目录或文件的磁盘使用情况
ping:测试网络连通性
ifconfig:显示或配置网络接口
netstat:显示网络连接、路由表、接口状态等信息
ssh user@hostname:通过ssh连接到远程主机
静态库和动态库如何制作及使用,区别是什么?
在Linux环境中,静态库和动态库都是用于共享代码的库文件。
它们的主要区别在于代码如何链接到可执行文件以及在运行时的行为。
制作静态库
- 编译源文件:首先将源文件编译为目标文件 gcc -c file1.c file2.c
- 创建静态库:使用ar工具将多个目标文件打包成一个静态库(.a文件)ar rcs libmylib.a file1.o file2.o
链接静态库
gcc main.c -L. -lmylib -o main
-L.指定库文件路径为当前目录
-lmylib:指定库名称
制作动态库
-
编译源文件。使用-fPIC选项将源文件编译为位置无关代码的目标文件(.o文件)。gcc -fPIC -c file1.c file2.c
-
创建动态库:使用gcc将目标文件打包成一个动态库(.so文件)gcc -shared -o libmylib.so file1.o file2.o
-
在编译时将动态库连接到可执行文件中。gcc main.c -L. -lmylib -o main
-
运行时设置库路径:确保动态库路径在运行时可见。gcc main.c -L. -lmylib -o main
命名方式不同:
静态库:libxxx.a
动态库:libxxx.so
链接时间和方式不同:
静态库的链接是将整个库函数的所有数据在编译时都整合进了目标代码。
动态库的链接是程序执行到哪个函数链接哪个函数的库。
静态库优点:
发布程序时无需提供静态库,移植方便,运行速度相对快些
缺点:
静态链接生成的可执行文件体积较大,消耗内存,如果所使用的静态库发生更新改变,程序必须重新编译,更新麻烦。
- 动态库优缺点 - 优点:更加节省内存并减少页面交换,动态库改变并不影响使用的程序,动态函数库升级比较方便 - 缺点:发布程序时需要提供动态库
GDB常见的调试命令
GDB(GNU Debugger)是用于调试程序的强大工具。
启动与退出:
- gdb program:启动GDB并加载程序
- quit:退出GDB
运行程序:
- run [args] 启动程序并传递参数
- start:启动程序并在main函数处停止
- kill:终止正在运行的程序
设置断点:
- break function:指定函数处设置断点
- break line:指定文件的某一行设置断点
- break address:指定内存地址设置断点
- delete [breakpoint-number]:删除指定编号的断点。
控制执行:
- continue:继续执行程序直到遇到下一个断点
- next:单步执行,跳过函数调用
- step:单步执行,进入函数调用
- finish:运行到当前函数的末尾并返回
- until:运行到当前循环的末尾
检查状态:
- print expression:打印表达式的值
- info locals:显示当前堆栈帧的所有局部变量
- info args:显示当前函数的参数
- backtrace:显示当前调用堆栈
- info breakpoints:显示所有断点的信息
进程调度算法
- 先来先服务:每次调度都是从(进程)队列中选择一个或多个最先进入该队列的作业(进程),将它们调入内存,为它们分配资源、创建进程,当每个进程就绪后,它加入就绪队列。当前正运行的进程停止执行,选择在就绪队列中存在时间最长的进程运行。
- 短作业优先(SJF)调度算法 短作业优先(SJF)的调度算法是从后备队列中选择一个或若干个估计运行时间最短的作业(进程),将它们调入内存运行,短进程优先(SPF)调度算法从就绪队列中选择一个估计运行时间最短的进程,将处理机分配给它,使之立即执行,直到完成或者发生某件事而阻塞时,才释放处理机。
- 优先级调度算法 优先级调度算法又称优先权调度算法,该算法既可以用于作业调度,也可以用于进程调度,该算法中的优先级用于描述作业运行的紧迫程度。在作业调度中,优先级调度算法每次从后备作业队列中选择优先级最髙的一个或几个作业,将它们调入内存,分配必要的资源,创建进程并放入就绪队列;在进程调度中,优先级调度算法每次从就绪队列中选择优先级最高的进程,将处理机分配给它,使之投入运行。
- 高响应比优先调度算法 高响应比优先调度算法主要用于作业调度,该算法是对 FCFS 调度算法和 SJF 调度算法的一种综合平衡,同时考虑每个作业的等待时间和估计的运行时间。在每次进行作业调度时,先计算后备作业队列中每个作业的响应比,从中选出响应比最高的作业投入运行。
- 时间片轮转调度算法 时间片轮转调度算法主要适用于分时系统。每次调度时,把 CPU 分配给队首进程,并令其执行一个时间片。时间片的大小从几 ms 到几百 ms。当执行的时间片用完时,由一个计时器发出时钟中断请求,调度程序便据此信号来停止该进程的执行,并将它送往就绪队列的末尾;然后,再把处理机分配给就绪队列中新的队首进程,同时也让它执行一个时间片。
- 多级反馈队列调度算法 多级反馈队列调度算法是时间片轮转调度算法和优先级调度算法的综合和发展,通过动态调整进程优先级和时间片大小,多级反馈队列调度算法可以兼顾多方面的系统目标。
大端、小端
大端和小端指的是字节序,就是大于一个字节类型的数据在内存中的存放顺序。字节序分为大端字节序和小端字节序。
- 大端字节序:最高位字节存储在内存的低地址处。
- 小端字节序:最高位字节存储在内存的高地址处
什么是孤儿进程,什么是僵尸进程,如何解决僵尸进程
孤儿进程
孤儿进程是其父进程已经终止但它仍然在运行的进程。
当父进程终止时,这些孤儿进程将被系统的systemd收养,由它们负责清理。
系统会自动处理孤儿进程。init进程会接管这些孤儿进程,并调用wait系统调用清理它们的资源。
僵尸进程
僵尸进程是已经终止但其退出状态信息仍然保留在进程表中的进程。
僵尸进程保留在进程表中,直到其父进程读取了它们的退出状态。僵尸进程不会消耗任何CPU或内存资源,但会占用进程表项。
僵尸进程通常是由父进程未能正确调用wait或waitpid系统调用来获取子进程的退出状态而产生的。
父进程在适当的时机调用wait或waitpid来等待子进程终止,并获取其退出状态,从而防止产生僵尸进程。
捕捉SIGCHILD信号
父进程可以捕捉SIGCHILD信号,当子进程终止时,SIGCHILD信号会发给父进程。父进程可以在信号处理函数中调用wait或waitid来清理僵尸进程。
忽略SIGCHILD信号
signal(SIGCHLD, SIG_IN);父进程可以通过设置SIGCHLD信号的处理行为为SIG_IN忽略它。这样子进程终止时系统会自动清理僵尸进程。
孤儿进程:孤儿进程是指一个父进程退出后,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被init进程(进程号为1)所收养,并且由init进程对它们完整状态收集工作,孤儿进程一般不会产生任何危害。
僵尸进程:僵尸进程是指一个进程使用for()函数创建子进程,如果子进程退出,而父进程并没有调用wait()或者waitpid()系统调用取得子进程的终止状态,那么子进程的进程描述符仍然保存在系统中,占用系统资源。
在fork()子进程之后,我们要及时在父进程中使用wait()或waitpid()系统调用,等子进程结束后,父进程回收子进程PCB的资源。同时,当子进程退出的时候,内核会给父进程一个CIGCHLD信号,所以可以建立一个捕获SIGCHLD信号的信号处理函数,在函数体中调用wt()或者wtpid(),就可以清理退出的子进程以达到防止僵尸进程的目的。
进程通信的方式有哪些?
管道
匿名管道
- 特点:只能在具有亲缘关系的进程之间使用(例如父子进程)。
- 数据以字节流的形式通过管道传输。
命名管道
可用于无亲缘关系的进程之间,通过文件系统中的文件名进行通信。
消息队列
消息被放入消息队列可以按顺序或优先级读取
共享内存
进程可以直接访问共享的内存区域,是最快的IPC方式之一。
通过共享内存段实现数据的直接共享,通常配合信号量使用来控制对共享内存的访问。
信号量
信号量用于进程间的互斥和同步。
套接字
用于不同主机之间的通信,但也可以用于本地进程间通信(Unix域套接字)。
通过网络接口进行数据传输。
总结
- 管道:管道也叫无名管道,本质其实是内核中维护的一块内存缓冲区,Linux系统中通过pipe()函数创建管道,会生成两个文件描述符,分别对应管道的读端和写端。无名管道只能用于具有亲缘关系的进程间的通信。
- 命名管道,FIFO文件。有名管道提供了一个路径名与之关联,以FIFO的文件形式存在于文件系统中,并且其打开方式与打开一个普通文件是一样的,这样即使与FIFO的创建进程不存在亲缘管理,只要可以访问该路径,就能够彼此通过FIFO通信。
- 信号,是事件发生时对进程的通知机制,有时也称为软件中断,它是在软件层次上对中断机制的一种模拟,是一种异步通信的方式。信号可以导致一个正在运行的进程被另一个正在运行的异步进程中断,转而处理某一个突发事件。
- …