
UCB: Sysadmin DeCal Lab4
UCB: Sysadmin DeCal Lab4
课程介绍
来自 UCB 的一门讲解 Linux 的入门课程,比起定位相同的 MIT 的公开课 Missing Semester,Decal 讲解得更加系统、也更加清晰,这也是我推荐它的主要原因。比起 Missing Semester 更像是给已经开始编程但没有系统使用过这些工具的学生的查缺补漏,DeCal 更像是面向零基础的同学的课程。一共十二周的课程内容,包括 Linux 基础、shell 编程(还有tmux 、vim)、包管理、服务(Services)、基础计算机网络、网络服务、安全(密钥管理)、Git、Docker、Kubernetes、Puppet 和 CUDA。 十分适合新手了解和入门 Linux 环境相关内容。
课程链接:https://decal.ocf.berkeley.edu/labs/4/
Lab4 - Services and Processes
Process 进程
A process is asingle instance of a program.
Processes are isolated from one another and have their ownmemory, threads, etc. (Additional isolation, such as filesystem or network isolation, is also possible.)
每个进程都含有以下内容:
PID: Process ID
PPID: Parent’s PID
UID: User running the process
The program (executable) that the process is running
The args (command line) of the process
查看进程
我们可以用 ps
命令查看进程。
root@# ps
PID TTY TIME CMD
20646 pts/4 00:00:00 sudo
20647 pts/4 00:00:00 su
20649 pts/4 00:00:00 bash
27880 pts/4 00:00:00 ps
这时如果我们打开另一个控制台,输入:
sleep 100
再回到原控制台使用 ps
命令,会发现我们并没有看到 sleep
这个进程。因为不加任何选项我们只会看到当前控制台的进程(与 TTY 这一列有关系)。
我们最常用的是 ps -ef
命令。
-e:显示所有进程。
-f:显示进程关系。
而一般这个命令显示的进程太多,为了便于我们查找,我们可以这样做:
ps -ef | grep 进程关键字
root@LAPTOP-M3IADGND:/# sleep 1000 &
[1] 32759
root@LAPTOP-M3IADGND:/# ps -ef | grep sleep
root 32759 28430 0 13:11 pts/2 00:00:00 sleep 1000
root 32821 28430 0 13:11 pts/2 00:00:00 grep --color=auto sleep
我们就可以用 kill
命令杀死这个进程了
root@LAPTOP-M3IADGND:/home/donnie# sleep 100 &
[1] 37056
root@LAPTOP-M3IADGND:/home/donnie# ps -ef | grep sleep
root 37056 20649 0 13:29 pts/4 00:00:00 sleep 100
root 37103 20649 0 13:29 pts/4 00:00:00 grep --color=auto sleep
root@LAPTOP-M3IADGND:/home/donnie# kill 37056
root@LAPTOP-M3IADGND:/home/donnie# ps -ef | grep sleep
root 37277 20649 0 13:30 pts/4 00:00:00 grep --color=auto sleep
[1]+ 已终止 sleep 100
进程的继承
系统启动时会启动一个进程 PID 1
,用于管理其余所有的服务和进程。
在控制台输入 htop
回车,并按下 F5
:
可以看到每一个进程都有它的 Parent 进程(除了 PID 1),而每个进程都可以由许多子进程。
htop
可以被看作是ps -ef
的一个更广泛的版本,它可以实时更新进程统计信息。
进程与线程
一个进程由一个或多个线程。
每个进程有自己的数据和代码,进程间必须使用 pipes
或者文件来进行交流;
而多个线程可以共享同一个进程,但是有不同的系统状态。
创建新进程
以下是一段可以获得当前进程PID的C语言代码 henlo.c
:
#include<stdio.h>
int main( void ) {
printf( "henlo: %d\n", getpid() );
}
编译并运行它,我们可以得到:
# gcc henlo.c -o henlo
# ./henlo
henlo: 10455
使用C语言的 fork()
,我们可以直接复制当前进程,在当前进程上创建一个子进程:
/*linux下:*/
#include <stdio.h>
#include <unistd.h>
int main() {
// #define pit_t int
pid_t pid;
pid = fork();
if(pid == 0) {
// 返回子进程
printf("child pid: %d\n", getpid());
} else {
printf("pid: %d\n", pid);//父进程中返回子进程的pid
printf("father pid: %d\n", getpid());
}
}
# gcc fork.c -o fork
# ./fork
pid: 13895
father pid: 13894
child pid: 13895
fork调用的一个奇妙之处就是它仅仅被调用一次,却能够返回两次,它可能有三种不同的返回值:
1)在父进程中,fork返回新创建子进程的进程ID;
2)在子进程中,fork返回0;
3)如果出现错误,fork返回一个负值;
我们可以在子进程内编写一些命令:
#include<stdio.h>
int main( void ) {
if ( fork() > 0 ) {
/* parent process */
wait( NULL );
} else {
/* child process */
execv( “/bin/bash”, NULL );
}
}
// 之后在命令行连续三次运行编译好的exec文件
:(){ :|:& };:
这看起来像是一个 Unix/Linux 系统上的典型的 fork 炸弹,也称为“fork bomb”。它是一个简单的 Shell 脚本,会导致系统因为无限递归的进程复制而崩溃。这个脚本会定义一个函数,这个函数会调用自身两次,然后这两个函数又会调用自身,导致指数级地增加进程数量,最终耗尽系统的资源。
僵尸进程
若子进程先于父进程退出 (如C语言的 exit(1)
),且父进程无暇回收子进程的资源,子进程就会变为僵尸进程。
僵尸进程无法使用 kill
命令杀死。
解决方案:杀死父进程,这些僵尸子进程会被 init
线程领养并继续回收。
详细见: https://www.cnblogs.com/yychuyu/p/15553400.html
Services
Lab5 - Introduction to Networking
待补充……
Lab6 - Web Servers
待补充……
参考
Linux pid_t 类型的定义 https://blog.csdn.net/K346K346/article/details/80212265
简述C语言fork()函数用法 https://blog.csdn.net/cuit2016123070/article/details/83280125