新网创想网站建设,新征程启航
为企业提供网站建设、域名注册、服务器等服务
方法一:PS
饶阳ssl适用于网站、小程序/APP、API接口等需要进行数据传输应用场景,ssl证书未来市场广阔!成为成都创新互联公司的ssl证书销售渠道,可以享受市场价格4-6折优惠!如果有意向欢迎电话联系或者加微信:028-86922220(备注:SSL证书合作)期待与您的合作!
在ps命令中,“-T”选项可以开启线程查看。下面的命令列出了由进程号为pid的进程创建的所有线程。
1.$ ps -T -p pid
“SID”栏表示线程ID,而“CMD”栏则显示了线程名称。
方法二: Top
top命令可以实时显示各个线程情况。要在top输出中开启线程查看,请调用top命令的“-H”选项,该选项会列出所有Linux线程。在top运行时,你也可以通过按“H”键将线程查看模式切换为开或关。
1.$ top -H
要让top输出某个特定进程pid并检查该进程内运行的线程状况:
$ top -H -p pid
1.调度器的概述
多任务操作系统分为非抢占式多任务和抢占式多任务。与大多数现代操作系统一样,Linux采用的是抢占式多任务模式。这表示对CPU的占用时间由操作系统决定的,具体为操作系统中的调度器。调度器决定了什么时候停止一个进程以便让其他进程有机会运行,同时挑选出一个其他的进程开始运行。
2.调度策略
在Linux上调度策略决定了调度器是如何选择一个新进程的时间。调度策略与进程的类型有关,内核现有的调度策略如下:
#define SCHED_NORMAL 0#define SCHED_FIFO 1#define SCHED_RR 2#define SCHED_BATCH 3/* SCHED_ISO: reserved but not implemented yet */#define SCHED_IDLE 5
0: 默认的调度策略,针对的是普通进程。
1:针对实时进程的先进先出调度。适合对时间性要求比较高但每次运行时间比较短的进程。
2:针对的是实时进程的时间片轮转调度。适合每次运行时间比较长得进程。
3:针对批处理进程的调度,适合那些非交互性且对cpu使用密集的进程。
SCHED_ISO:是内核的一个预留字段,目前还没有使用
5:适用于优先级较低的后台进程。
注:每个进程的调度策略保存在进程描述符task_struct中的policy字段
3.调度器中的机制
内核引入调度类(struct sched_class)说明了调度器应该具有哪些功能。内核中每种调度策略都有该调度类的一个实例。(比如:基于公平调度类为:fair_sched_class,基于实时进程的调度类实例为:rt_sched_class),该实例也是针对每种调度策略的具体实现。调度类封装了不同调度策略的具体实现,屏蔽了各种调度策略的细节实现。
调度器核心函数schedule()只需要调用调度类中的接口,完成进程的调度,完全不需要考虑调度策略的具体实现。调度类连接了调度函数和具体的调度策略。
武特师兄关于sche_class和sche_entity的解释,一语中的。
调度类就是代表的各种调度策略,调度实体就是调度单位,这个实体通常是一个进程,但是自从引入了cgroup后,这个调度实体可能就不是一个进程了,而是一个组
4.schedule()函数
linux 支持两种类型的进程调度,实时进程和普通进程。实时进程采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL策略。
preempt_disable():禁止内核抢占
cpu_rq():获取当前cpu对应的就绪队列。
prev = rq-curr;获取当前进程的描述符prev
switch_count = prev-nivcsw;获取当前进程的切换次数。
update_rq_clock() :更新就绪队列上的时钟
clear_tsk_need_resched()清楚当前进程prev的重新调度标志。
deactive_task():将当前进程从就绪队列中删除。
put_prev_task() :将当前进程重新放入就绪队列
pick_next_task():在就绪队列中挑选下一个将被执行的进程。
context_switch():进行prev和next两个进程的切换。具体的切换代码与体系架构有关,在switch_to()中通过一段汇编代码实现。
post_schedule():进行进程切换后的后期处理工作。
5.pick_next_task函数
选择下一个将要被执行的进程无疑是一个很重要的过程,我们来看一下内核中代码的实现
对以下这段代码说明:
1.当rq中的运行队列的个数(nr_running)和cfs中的nr_runing相等的时候,表示现在所有的都是普通进程,这时候就会调用cfs算法中的pick_next_task(其实是pick_next_task_fair函数),当不相等的时候,则调用sched_class_highest(这是一个宏,指向的是实时进程),这下面的这个for(;;)循环中,首先是会在实时进程中选取要调度的程序(p = class-pick_next_task(rq);)。如果没有选取到,会执行class=class-next;在class这个链表中有三种类型(fair,idle,rt).也就是说会调用到下一个调度类。
static inline struct task_struct *pick_next_task(struct rq *rq){ const struct sched_class *class; struct task_struct *p; /*
* Optimization: we know that if all tasks are in
* the fair class we can call that function directly:
*///基于公平调度的普通进程
if (likely(rq-nr_running == rq-cfs.nr_running)) {
p = fair_sched_class.pick_next_task(rq); if (likely(p)) return p;
}//基于实时调度的实时进程
class = sched_class_highest; for ( ; ; ) {
p = class-pick_next_task(rq); //实时进程的类
if (p) return p; /*
* Will never be NULL as the idle class always
* returns a non-NULL p:
*/
class = class-next; //rt-next = fair; fair-next = idle
}
}
在这段代码中体现了Linux所支持的两种类型的进程,实时进程和普通进程。回顾下:实时进程可以采用SCHED_FIFO 和SCHED_RR调度策略,普通进程采用SCHED_NORMAL调度策略。
在这里首先说明一个结构体struct rq,这个结构体是调度器管理可运行状态进程的最主要的数据结构。每个cpu上都有一个可运行的就绪队列。刚才在pick_next_task函数中看到了在选择下一个将要被执行的进程时实际上用的是struct rq上的普通进程的调度或者实时进程的调度,那么具体是如何调度的呢?在实时调度中,为了实现O(1)的调度算法,内核为每个优先级维护一个运行队列和一个DECLARE_BITMAP,内核根据DECLARE_BITMAP的bit数值找出非空的最高级优先队列的编号,从而可以从非空的最高级优先队列中取出进程进行运行。
我们来看下内核的实现
struct rt_prio_array {
DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */
struct list_head queue[MAX_RT_PRIO];
};
数组queue[i]里面存放的是优先级为i的进程队列的链表头。在结构体rt_prio_array 中有一个重要的数据构DECLARE_BITMAP,它在内核中的第一如下:
define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
5.1对于实时进程的O(1)算法
这个数据是用来作为进程队列queue[MAX_PRIO]的索引位图。bitmap中的每一位与queue[i]对应,当queue[i]的进程队列不为空时,Bitmap的相应位就为1,否则为0,这样就只需要通过汇编指令从进程优先级由高到低的方向找到第一个为1的位置,则这个位置就是就绪队列中最高的优先级(函数sched_find_first_bit()就是用来实现该目的的)。那么queue[index]-next就是要找的候选进程。
如果还是不懂,那就来看两个图
注:在每个队列上的任务一般基于先进先出的原则进行调度(并且为每个进程分配时间片)
在内核中的实现为:
static struct sched_rt_entity *pick_next_rt_entity(struct rq *rq, struct rt_rq *rt_rq){ struct rt_prio_array *array = rt_rq-active; struct sched_rt_entity *next = NULL; struct list_head *queue; int idx;
idx = sched_find_first_bit(array-bitmap); //找到优先级最高的位
BUG_ON(idx = MAX_RT_PRIO); queue = array-queue + idx; //然后找到对应的queue的起始地址
next = list_entry(queue-next, struct sched_rt_entity, run_list); //按先进先出拿任务
return next;
}
那么当同一优先级的任务比较多的时候,内核会根据
位图:
将对应的位置为1,每次取出最大的被置为1的位,表示优先级最高:
5.2 关于普通进程的CFS算法:
我们知道,普通进程在选取下一个需要被调度的进程时,是调用的pick_next_task_fair函数。在这个函数中是以调度实体为单位进行调度的。其最主要的函数是:pick_next_entity,在这个函数中会调用wakeup_preempt_entity函数,这个函数的主要作用是根据进程的虚拟时间以及权重的结算进程的粒度,以判断其是否需要抢占。看一下内核是怎么实现的:
wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
{
s64 gran, vdiff = curr-vruntime - se-vruntime;//计算两个虚拟时间差//如果se的虚拟时间比curr还大,说明本该curr执行,无需抢占
if (vdiff = 0) return -1;
gran = wakeup_gran(curr, se); if (vdiff gran) return 1; return 0;
}
gran为需要抢占的时间差,只有两个时间差大于需要抢占的时间差,才需要抢占,这里避免太频繁的抢占
wakeup_gran(struct sched_entity *curr, struct sched_entity *se)
{
unsigned long gran = sysctl_sched_wakeup_granularity; if (cfs_rq_of(curr)-curr sched_feat(ADAPTIVE_GRAN))
gran = adaptive_gran(curr, se);
/*
* Since its curr running now, convert the gran from real-time
* to virtual-time in his units.
*/ if (sched_feat(ASYM_GRAN)) {
/*
* By using 'se' instead of 'curr' we penalize light tasks, so
* they get preempted easier. That is, if 'se' 'curr' then
* the resulting gran will be larger, therefore penalizing the
* lighter, if otoh 'se' 'curr' then the resulting gran will
* be smaller, again penalizing the lighter task.
*
* This is especially important for buddies when the leftmost
* task is higher priority than the buddy.
*/ if (unlikely(se-load.weight != NICE_0_LOAD))
gran = calc_delta_fair(gran, se);
} else { if (unlikely(curr-load.weight != NICE_0_LOAD))
gran = calc_delta_fair(gran, curr);
} return gran;
}
6.调度中的nice值
首先需要明确的是:nice的值不是进程的优先级,他们不是一个概念,但是进程的Nice值会影响到进程的优先级的变化。
通过命令ps -el可以看到进程的nice值为NI列。PRI表示的是进程的优先级,其实进程的优先级只是一个整数,它是调度器选择进程运行的基础。
普通进程有:静态优先级和动态优先级。
静态优先级:之所有称为静态优先级是因为它不会随着时间而改变,内核不会修改它,只能通过系统调用nice去修改,静态优先级用进程描述符中的static_prio来表示。在内核中/kernel/sched.c中,nice和静态优先级的关系为:
#define NICE_TO_PRIO(nice) (MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ((prio) - MAX_RT_PRIO - 20)
动态优先级:调度程序通过增加或者减小进程静态优先级的值来奖励IO小的进程或者惩罚cpu消耗型的进程。调整后的优先级称为动态优先级。在进程描述中用prio来表示,通常所说的优先级指的是动态优先级。
由上面分析可知,我们可以通过系统调用nice函数来改变进程的优先级。
#include stdlib.h#include stdio.h#include math.h#include unistd.h#include sys/time.h#define JMAX (400*100000)#define GET_ELAPSED_TIME(tv1,tv2) ( \
(double)( (tv2.tv_sec - tv1.tv_sec) \
+ .000001 * (tv2.tv_usec - tv1.tv_usec)))//做一个延迟的计算double do_something (void){ int j; double x = 0.0; struct timeval tv1, tv2;
gettimeofday (tv1, NULL);//获取时区
for (j = 0; j JMAX; j++)
x += 1.0 / (exp ((1 + x * x) / (2 + x * x)));
gettimeofday (tv2, NULL); return GET_ELAPSED_TIME (tv1, tv2);//求差值}int main (int argc, char *argv[]){ int niceval = 0, nsched; /* for kernels less than 2.6.21, this is HZ
for tickless kernels this must be the MHZ rate
e.g, for 2.6 GZ scale = 2600000000 */
long scale = 1000; long ticks_cpu, ticks_sleep; pid_t pid;
FILE *fp; char fname[256]; double elapsed_time, timeslice, t_cpu, t_sleep; if (argc 1)
niceval = atoi (argv[1]);
pid = getpid (); if (argc 2)
scale = atoi (argv[2]); /* give a chance for other tasks to queue up */
sleep (3); sprintf (fname, "/proc/%d/schedstat", pid);//读取进程的调度状态
/*
在schedstat中的数字是什么意思呢?:
*/
/* printf ("Fname = %s\n", fname); */
if (!(fp = fopen (fname, "r"))) { printf ("Failed to open stat file\n"); exit (-1);
} //nice系统调用
if (nice (niceval) == -1 niceval != -1) { printf ("Failed to set nice to %d\n", niceval); exit (-1);
}
elapsed_time = do_something ();//for 循环执行了多长时间
fscanf (fp, "%ld %ld %d", ticks_cpu, ticks_sleep, nsched);//nsched表示调度的次数
t_cpu = (float)ticks_cpu / scale;//震动的次数除以1000,就是时间
t_sleep = (float)ticks_sleep / scale;
timeslice = t_cpu / (double)nsched;//除以调度的次数,就是每次调度的时间(时间片)
printf ("\nnice=%3d time=%8g secs pid=%5d"
" t_cpu=%8g t_sleep=%8g nsched=%5d"
" avg timeslice = %8g\n",
niceval, elapsed_time, pid, t_cpu, t_sleep, nsched, timeslice);
fclose (fp); exit (0);
}
说明: 首先说明的是/proc/[pid]/schedstat:在这个文件下放着3个变量,他们分别代表什么意思呢?
第一个:该进程拥有的cpu的时间
第二个:在对列上的等待时间,即睡眠时间
第三个:被调度的次数
由结果可以看出当nice的值越小的时候,其睡眠时间越短,则表示其优先级升高了。
7.关于获取和设置优先级的系统调用:sched_getscheduler()和sched_setscheduler
#include sched.h#include stdlib.h#include stdio.h#include errno.h#define DEATH(mess) { perror(mess); exit(errno); }void printpolicy (int policy){ /* SCHED_NORMAL = SCHED_OTHER in user-space */
if (policy == SCHED_OTHER) printf ("policy = SCHED_OTHER = %d\n", policy); if (policy == SCHED_FIFO) printf ("policy = SCHED_FIFO = %d\n", policy); if (policy == SCHED_RR) printf ("policy = SCHED_RR = %d\n", policy);
}int main (int argc, char **argv){ int policy; struct sched_param p; /* obtain current scheduling policy for this process */
//获取进程调度的策略
policy = sched_getscheduler (0);
printpolicy (policy); /* reset scheduling policy */
printf ("\nTrying sched_setscheduler...\n");
policy = SCHED_FIFO;
printpolicy (policy);
p.sched_priority = 50; //设置优先级为50
if (sched_setscheduler (0, policy, p))
DEATH ("sched_setscheduler:"); printf ("p.sched_priority = %d\n", p.sched_priority); exit (0);
}
输出结果:
[root@wang schedule]# ./get_schedule_policy policy = SCHED_OTHER = 0
Trying sched_setscheduler...
policy = SCHED_FIFO = 1
p.sched_priority = 50
可以看出进程的优先级已经被改变。
任务调度的crond常驻命令
crond 是linux用来定期执行程序的命令。当安装完成操作系统之后,默认便会启动此任务调度命令。crond命令每分锺会定期检查是否有要执行的工作,如果有要执行的工作便会自动执行该工作。而linux任务调度的工作主要分为以下两类:
1、系统执行的工作:系统周期性所要执行的工作,如备份系统数据、清理缓存
2、个人执行的工作:某个用户定期要做的工作,例如每隔10分钟检查邮件服务器是否有新信,这些工作可由每个用户自行设置
Crontab是UNIX系统下的定时任务触发器,其使用者的权限记载在下列两个文件中:
文件
含义
/etc/cron.deny
该文件中所列的用户不允许使用Crontab命令
/etc/cron.allow
该文件中所列的用户允许使用Crontab命令
/var/spool/cron/
是所有用户的crontab文件
/var/spool/cron/crontabs
/var/spool/cron/crontabs
Crontab命令的格式为:crontab –l|-r|-e|-i [username],其参数含义如表一:
参数名称
含义
示例
-l
显示用户的Crontab文件的内容
crontabl –l
-i
删除用户的Crontab文件前给提示
crontabl -ri
-r
从Crontab目录中删除用户的Crontab文件
crontabl -r
-e
编辑用户的Crontab文件
crontabl -e
用户所建立的Crontab文件存于/var/spool/cron中,其文件名与用户名一致。
它的格式共分为六段,前五段为时间设定段,第六段为所要执行的命令段,
格式如下:* * * * *
其时间段的含义如表二:
段
含义
取值范围
第一段
代表分钟
0—59
第二段
代表小时
0—23
第三段
代表日期
1—31
第四段
代表月份
1—12
第五段
代表星期几,0代表星期日
0—6
例:如果用户的Crontab文件的内容是:29 19 * * * echo its dinner time,则系统每天的19:29显示‘its dinner time’
示例(创建一个cron全过程,每分钟都会在test.txt里输入当前时间):
1. 以普通用户登录linux系统(我用的是CentOS4.1)
2. $crontab –e
说明:系统默认的编辑器是VIM,如果不是请加上以下shell:
$EDITOR=vi
$export EDITOR
3. 输入”*/1 * * * * date $HOME/test.txt”,save and exit VIM
4. $su root
5. $cd /etc/init.d
6. ./crond restart
下面看看看几个具体的例子:
● 0 */2 * * * /sbin/service httpd restart 意思是每两个小时重启一次apache
● 50 7 * * * /sbin/service sshd start 意思是每天7:50开启ssh服务
● 50 22 * * * /sbin/service sshd stop 意思是每天22:50关闭ssh服务
● 0 0 1,15 * * fsck /home 每月1号和15号检查/home 磁盘
● 1 * * * * /home/bruce/backup 每小时的第一分执行 /home/bruce/backup这个文件
● 00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} /; 每周一至周五3点钟,在目录/home中,查找文件名为*.xxx的文件,并删除4天前的文件。
● 30 6 */10 * * ls 意思是每月的1、11、21、31日是的6:30执行一次ls命令
参数 :
crontab -e : 执行文字编辑器来设定时程表,内定的文字编辑器是 VI,如果你想用别的文字编辑器,则请先设定 VISUAL 环境变数来指定使用那个文字编辑器(比如说 setenv VISUAL joe)
crontab -r : 删除目前的时程表
crontab -l : 列出目前的时程表
crontab file [-u user]-用指定的文件替代目前的crontab。
时程表的格式如下 :
f1 f2 f3 f4 f5 program
其中 f1 是表示分钟,f2 表示小时,f3 表示一个月份中的第几日,f4 表示月份,f5 表示一个星期中的第几天。program 表示要执行的程序。
当 f1 为 * 时表示每分钟都要执行 program,f2 为 * 时表示每小时都要执行程序,其馀类推
当 f1 为 a-b 时表示从第 a 分钟到第 b 分钟这段时间内要执行,f2 为 a-b 时表示从第 a 到第 b 小时都要执行,其馀类推
当 f1 为 */n 时表示每 n 分钟个时间间隔执行一次,f2 为 */n 表示每 n 小时个时间间隔执行一次,其馀类推
当 f1 为 a, b, c,... 时表示第 a, b, c,... 分钟要执行,f2 为 a, b, c,... 时表示第 a, b, c...个小时要执行,其馀类推
使用者也可以将所有的设定先存放在档案 file 中,用 crontab file 的方式来设定时程表。
crontab执行java程序的问题:
一 crontab使用注意:
crontab -l查看该用户的crontab配置,crontab -e编辑该用户的crontab配置配置一般在末尾加上 21表示错误输出(2)和标准输出(1)一样输出到同一个由前面指定的地方
如 15 14 * * * /sys_back/monitor.sh /sys_back/log/monitor.log 21
表示每天14:15执行monitor.sh脚本,错误和标准输出都写入monitor.log文件
涉及到文件名时最好写绝对路径
二 问题及解决
shell脚本有echo语句,有java -jar执行java程序。直接执行脚本时,一切顺利,但是放到crontab中执行时,echo语句正常,java程序却没有执行。
1 网上查找,觉得应该是环境变量的问题。说是要将java环境变量加入到shell脚本中,按照
这个方法做,发现问题依然存在。百思不得其解。
2 经转换角度,看java程序是否有问题。在java语句中直接加入打印语句,发现其在crontab日志中
居然可以显示。终于确定是java程序的问题。java程序功能很简单,就是一个语句java -Dosgi.console -Dosgi.configuration.area=./configuration -jar equinox.jar -console用来启动osgi框架。
于是在shell脚本中不调用java程序,直接改为程序中的这一句,问题解决。
但是又引发新的问题:直接java -jar会源源不断的输出osgi到日志文件,导致日志文件越来越大。
不可行。再想办法解决。
3 感觉还是相对路径的问题。尝试在crontab调用的脚本中用相对路径向一个文件输出一句话,发现失败。(单独执行脚本没问题)既然如此,是不是java程序中也不能用相对路径呢。遂将./configuration及equinox.jar都用绝对路径,再调试,终于成功,至此问题解决。但始终感觉在程序中用绝对路径很不方便维护。
三 附加问题及解决
此脚本的作用就是判断osgi程序是否在运行,如果不运行则启动。
实现思路是ps -elf得到进程id及状态,如果id不存在,则启动,如果id存在但状态不是运行中(solaris为O,AIX为A),则杀掉原进程重新启动。
发现程序在运行几天后会自动停掉,以为是java程序有问题,然而却始终找不到问题在哪里。在解决上面问题时,却意外的发现可能不是java程序的问题。man ps时发现,solaris中,进程状态除了O,还有S(sleeping) R(Runnable) Z(Zombie僵尸进程)T(stopped),只有后两种状态下进程才是有问题的,所以很可能是crontab执行脚本时,程序状态非O就被杀掉,重启时却因为上面的问题没成功。于是修改脚本,状态是后两种时才重启。这个问题也解决了。
我也是网上转的,望采纳
先说下$和#在linux系统终端(命令行)中通常代表的什么: $打头的表示这不是在root用户(管理员用户)下执行的命令 #打头的和前者相反,即root用户下 再说如何使$变为#? 即在命令行中如何切换到root用户下: $su root 【键盘按回车】 输入root的密码 如果不知道root的密码,可以通过重新设置,但是下面的方法需要知道当前用户的密码: $sudo passwd root 【键盘按回车】 会提示输入当前用户的密码 接着会提示输入root的新密码 最后确认新密码 希望能帮到你,欢迎来到linux的世界。 不明白可以追问。
一,使用taskset充分利用多核cpu,让cpu的使用率均衡到每个cpu上
#taskset
-p, 设定一个已存在的pid,而不是重新开启一个新任务
-c, 指定一个处理,可以指定多个,以逗号分隔,也可指定范围,如:2,4,5,6-8。
1,切换某个进程到指定的cpu上
taskset -cp 3 13290
2,让某程序运行在指定的cpu上
taskset -c 1,2,4-7 tar jcf test.tar.gz test
需要注意的是,taskset -cp 3 13290在设定一个已经存在的pid时,子进程并不会继承父进程的,
因此像tar zcf xxx.tar.gz xxx这样的命令,最好在启动时指定cpu,如果在已经启动的情况下,则需要指定tar调用的gzip进程。
二,使用nice和renice设置程序执行的优先级
格式:nice [-n 数值] 命令
nice 指令可以改变程序执行的优先权等级。指令让使用者在执行程序时,指定一个优先等级,称之为 nice 值。
这个数值从最高优先级的-20到最低优先级的19。负数值只有 root 才有权力使。
一般使用者,也可使用 nice 指令来做执行程序的优先级管理,但只能将nice值越调越高。
可以通过二种方式来给某个程序设定nice值:
1,开始执行程序时给定一个nice值,用nice命令
2,调整某个运行中程序的PID的nice值,用renice命令
通常通过调高nice值来备份,为的是不占用非常多的系统资源。
例:
nice -n 10 tar zcf test.tar.gz test
由nice启动的程序,其子进程会继承父进程的nice值。
查看nice值
# nice -n -6 vim test.txt
# ps -l
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD
4 S 0 19427 2637 0 75 0 – 16551 wait pts/6 00:00:00 bash
4 T 0 21654 19427 0 71 -6 – 23464 finish pts/6 00:00:00 vim
renice调整运行中程序的nice值
格式:renice [nice值] PID
三,使用ulimit限制cpu占用时间
注意,ulimit 限制的是当前shell进程以及其派生的子进程。因此可以在脚本中调用ulimit来限制cpu使用时间。
例如,限制tar的cpu占用时间,单位秒。
# cat limit_cpu.sh
ulimit -SHt 100
tar test.tar.gz test
如果tar占用时间超过了100秒,tar将会退出,这可能会导致打包不完全,因此不推荐使用ulimit对cpu占用时间进行限制。
另外,通过修改系统的/etc/security/limits配置文件,可以针对用户进行限制。
四,使用程序自带的对cpu使用调整的功能
某些程序自带了对cpu使用调整的功能,比如nginx服务器,通过其配置文件,可以为工作进程指定cpu,如下:
worker_processes 3;
worker_cpu_affinity 0001 0010 0100 1000;
这里0001 0010 0100 1000是掩码,分别代表第1、2、3、4颗cpu核心,这就使得cpu的使用比较平均到每个核心上。