Part1: 任务调度
任务调度有两种:1)在特定时间执行一次的任务; 2) 周期性执行的任务。前者使用at命令创建,后者使用crontab命令创建。at命令背后的服务是atd,而crontab命令后面是cron服务。我们把常驻在内存的进程成为服务(daemon)。
#start service
/etc/init.d/atd restart
#set to start each time we start computer
chkconfig atd on
#how to use at
at [-mldv] TIME
at -c #JOB
-m use email to notice user about the execution
-l like 'atq' to see all the jobs in 'at'
-d like 'atrm' to remove job
-v use a comprehensive time
-c see what exactly the job will do
可以使用batch在CPU工作负载小于0.8时,才执行工作。CPU负载 = 同时执行的工作(进程)数量。负载越大,进程间切换的overhead越大。创建方法和at一样。batch TIME。
使用,crontab来创建周期性任务:
#basic use
crontab -e #edit the list of jobs
#if you are a root user
crontab -u username [-l-e-r] #see/ edit/ remove the jobs of a particular user
#Some gramma to use crontab
minutes hour day month Mon-Sun Command
# Notice that in Mon-Sun, you can input 0-7. 0 == 7, both of them mean Sunday.
# If you input *, it means whatever; input '7,9', it means at minute of 7 and 9; input '7-9', it means at minute of 7,8,9.
# If you input */5, it means every 5 (mins/hours,etc)
需要注意的是,如果使用-r将会清空该用户的所有任务。crontab -e是针对用户的cron来设计,如果是系统的例行性任务,编辑/etc/crontab这个文件即可。使用atacron命令可以使一些由于关机后无法执行的crontab命令在一开机就执行。
Linux的核心是权限控制,而出于安全性考虑,不能让所有人都执行at、batch、crontab和anacron命令。两者的管理方法是通过三种权限文件:
1、使用etc/at.allow,或者etc/cron.allow 只有清单内用户能使用;
2、使用etc/at.deny,或者etc/cron.deny 不在清单内都能使用;
3、不存在上述文件,只有root用户能使用;
Part2: 进程管理
Linux使用PID进行进程管理。不同的UID/GID导致他们所调用的程序(在磁盘上的可执行二进制文件)调用内存,产生不同的PID的进程(回顾操作系统教程可知,这里包括了进程的机器代码,栈区和数据区)。不同的PID对应着调用他们的UID/GID所产生的不同权限。如root能调用crontab -u去修改别的用户,而其他用户调用crontab只能调用crontab -e。
Linux的进程fork机制是所有的子进程和父进程共享环境变量,创建进行的过程:父进程复制自己产生一个一样的进程,只是PID和PPID(Parrent Program ID)不同。然后,修改子进程执行的代码,让其成为子进程。而所有的用户打开的子进程都是来自于一个祖先父进程:bash。这是每一个用户登录Linux第一个打开的进程。但是,真个系统的角度而言,真正的父进程是init。
多任务环境和同一环境下的任务管理(job control)问题:
多任务环境指的是Linux给每一个用户分配了7个任务环境(Alt + F1-7)。其中,F1-F6都是bash环境,而F7是图形界面。每一个bash进程之间相互隔离,无法以任务管理(job control)的方式管理对方的Jobs。但是可以使用ps -aux查看整个系统所打开的进程,从而如果其中一个bash环境down掉了,可以使用其它的bash关掉错误的进程恢复。
P.S.:如果想修改开机默认启动的bash数:etc/inittab;如果想限制别人远程链接打开的bash数:/etc/security/limits.conf。
每个bash的Job control实质是一个bash的前台和后台进程管理。前台(front ground)进程是可以有提示符和用户交换的进程,可以使用ctrl+c去终止的。后台(back ground)进程则反之。
那我们使用什么命令使进程变为后台进程?
#use &
cp file1 file2 & # let this process be in background
# screen will appear following content:
[1] 7400 # job_num PID
#job_num is a reference for jobs within one bash
#when you wait for a moment
[1]+ Done cp file1 file2
但是,变为后台进程并不能阻止该进程的stdout和stderr,只能使其运行时,不能和前台交互(前台可以继续进行别的事情)所以也不会受前台干扰(ctrl+c)。如果程序产生了stdout,我们无法使用ctrl + c去阻止。所以,一般而言,需要把会产生stdout的后台进程使用重定向将stdout/ stderr 导入文本文件。
放进后台运行的进程,如果exit了bash进程,将不能继续运行。如果需要能脱离bash继续运行的后台进程,需要使用nohup。
我们其实还能使用bg/ ctrl + z把一个正在运行的前台进程放入后台中运行/ 暂停。
#example of using ctrl+z
vim text
ctrl+z
[1]+ stopped vim text
#+means it is the default job which fg will take. It is the most recent one.
#using bg
cat text > text1
ctrl+z
[3]+ stopped cat text>text1
bg %3
#format is bg %[job_num]
Then the job number 3 will be running
#jobs
jobs [-l-r-s]
-l list job number and command, but also PID
-r only list the running job, but without PID
-s only list stopped job, but without PID
使用fg将后台进程来到前台运行:
#use of fg
fg %[job_num]
# if you don't assign the job_num, it will take the '+' one.
使用kill来关闭某个Job。其实kill最大的作用是关闭某个PID的进程,PID是通用于不同的bash,而Job number只是一个bash内的。
# kill a job
kill -[signal_num] %[job_num]
#signal number meaning:
-1 reload the program's metadata
-2 same with ctrl+c
-9 kill immediately
-15 end the program normally. Default one.
因为默认跟的数字是PID,所以需要加上%,以区分job number。
Part3:从个别的任务环境中走出来,看整体的系统环境的进程管理
在任意的一个bash环境,都可以使用ps或者top查看整个系统的所有进程。但两者还是有区别的,ps查看的时输入的时间点的进程信息,但top的信息会默认每5秒钟更新一次。
ps的使用方法:
#see all the processes in o.s.
ps aux
#see all the processes of me
ps -l # see the processes up to bash, instead of init.
top的使用方法:
# top
top -d num
top -bnp
#-d to assign how many seconds per update
# -p assign a particular PID to observe
# top -b -n 2 run the top twice
# input these command can achieve
?: see what are the commands can be inputed
P: sort the processes according to CPU usage
M: sort the processes according to memory usage
N: sort the processes according to PID
T: sort the processes according to CPU usage time
r: assign another nice value to PID
k: assign a particular signal to a PID
q: quit
介绍几个关于Linux进程的参数:
S代表STAT,有:R running, S sleep, D disabled, T, stop, Z zombie. Disabled是因为阻塞态,等待输入。Stop是由于按下了ctrl + z或者处于traced(除错)状态。僵尸进程的出现是因为这个进程已经执行结束或者出错了被终止了,但是其父进程未能完全的结束它,造成了进程一直在内存中。一般而言,需要交给init去管理,让系统通过内核的一些特殊处理来结束僵尸进程。如果不奏效,只能重启。
联系之前在操作系统中学习进程的知识,进程总体有三个状态:阻塞、就绪和运行。可以把stop和sleep当成特殊状态的就绪,但CPU暂时不能调用他们,得等待用户输入命令手动激活。
僵尸进程的出现原因有:进程的程序写的不好、系统不稳定等。但通常不能直接kill掉,因为可能会总有其父进程会一直创建它。需要找到它的父进程,看看能不能优化、改善。
鉴别僵尸进程通过状态或者CMD(command)后面跟着<defunct>。
TTY:代表进程是由哪个终端机打开的。如果是远程机,则是pts/0等,本地是tty1~tty6。
使用Top命令可以看到一些系统状态的总结,需要留意CPU那行的%wa,代表了I/O wait。通常,系统变慢是因为这项耗用CPU资源。同样,在swap那行,代表swap内存的使用,如果有很大的swap内存值,代表当前物理内存已经严重不足。
也可以使用pstree通过树的形式查看进程,是静态的。
#pstree
pstree [-A/-U] [-up]
#-A: use ASCII connect the processes
#-U use utf8 connect the processes
#-p see the PID of each process
#-u see the User of each process
结果可见,init的PID是1。
Part 4: 查看系统资源
用free查看内存的使用:
#free usage
free [-b/-k/-m/-g] [-t]
#b -- bytes, k -- KB, m -- MB, g -- GB.
#t -- display both physics memory and swap memory
通常物理内存快被用光是正常的,因为Linux想尽量加快系统性能,把尽可能多的内容放内存,加速读写。但swap内存则能不用则不用。
用uname查看与内核有关的信息:
#uname usage
uname [-asrmpi]
#-a all the -s, r, m, p, i are shown
including name/ version/ hardware(x86_64)/ CPU style
用uptime查看系统启动时间和工作负载
#uptime usage
uptime
actually it is the first line of top.
用netstat查看哪些进程使用了网络端口对外通信
这里引用DJ同学的通俗易懂的解释,socket其实就像是一个篮子,一个某个进程专属的收发信箱。专门负责这个进程和其它本机进程或者网络上其它机子的进程的通信。
#netstat usage
netstat [-atunlp]
#-a show all the tcp, udp and sockets
#-t only show tcp
#-u only show udp
#-n show the PID instead of showing the service name
#-l list all the listening services
#-p show the services' PID
如果直接列出-a,会看到protocol是unix的sockets。负责联系同一个系统的不同进程们。
用vmstat查看系统资源的动态变化:
#vmstat usage
vmstat
# default to show all the memory, swap, io, system, cpu
vmstat -fs # about the memory
vmstat -d #about the disk
vmstat -p partition #about the disk
默认的是: