方法一:PS
饒陽ssl適用于網(wǎng)站、小程序/APP、API接口等需要進(jìn)行數(shù)據(jù)傳輸應(yīng)用場(chǎng)景,ssl證書未來市場(chǎng)廣闊!成為成都創(chuàng)新互聯(lián)公司的ssl證書銷售渠道,可以享受市場(chǎng)價(jià)格4-6折優(yōu)惠!如果有意向歡迎電話聯(lián)系或者加微信:028-86922220(備注:SSL證書合作)期待與您的合作!
在ps命令中,“-T”選項(xiàng)可以開啟線程查看。下面的命令列出了由進(jìn)程號(hào)為pid的進(jìn)程創(chuàng)建的所有線程。
1.$ ps -T -p pid
“SID”欄表示線程ID,而“CMD”欄則顯示了線程名稱。
方法二: Top
top命令可以實(shí)時(shí)顯示各個(gè)線程情況。要在top輸出中開啟線程查看,請(qǐng)調(diào)用top命令的“-H”選項(xiàng),該選項(xiàng)會(huì)列出所有Linux線程。在top運(yùn)行時(shí),你也可以通過按“H”鍵將線程查看模式切換為開或關(guān)。
1.$ top -H
要讓top輸出某個(gè)特定進(jìn)程pid并檢查該進(jìn)程內(nèi)運(yùn)行的線程狀況:
$ top -H -p pid
1.調(diào)度器的概述
多任務(wù)操作系統(tǒng)分為非搶占式多任務(wù)和搶占式多任務(wù)。與大多數(shù)現(xiàn)代操作系統(tǒng)一樣,Linux采用的是搶占式多任務(wù)模式。這表示對(duì)CPU的占用時(shí)間由操作系統(tǒng)決定的,具體為操作系統(tǒng)中的調(diào)度器。調(diào)度器決定了什么時(shí)候停止一個(gè)進(jìn)程以便讓其他進(jìn)程有機(jī)會(huì)運(yùn)行,同時(shí)挑選出一個(gè)其他的進(jìn)程開始運(yùn)行。
2.調(diào)度策略
在Linux上調(diào)度策略決定了調(diào)度器是如何選擇一個(gè)新進(jìn)程的時(shí)間。調(diào)度策略與進(jìn)程的類型有關(guān),內(nèi)核現(xiàn)有的調(diào)度策略如下:
#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: 默認(rèn)的調(diào)度策略,針對(duì)的是普通進(jìn)程。
1:針對(duì)實(shí)時(shí)進(jìn)程的先進(jìn)先出調(diào)度。適合對(duì)時(shí)間性要求比較高但每次運(yùn)行時(shí)間比較短的進(jìn)程。
2:針對(duì)的是實(shí)時(shí)進(jìn)程的時(shí)間片輪轉(zhuǎn)調(diào)度。適合每次運(yùn)行時(shí)間比較長(zhǎng)得進(jìn)程。
3:針對(duì)批處理進(jìn)程的調(diào)度,適合那些非交互性且對(duì)cpu使用密集的進(jìn)程。
SCHED_ISO:是內(nèi)核的一個(gè)預(yù)留字段,目前還沒有使用
5:適用于優(yōu)先級(jí)較低的后臺(tái)進(jìn)程。
注:每個(gè)進(jìn)程的調(diào)度策略保存在進(jìn)程描述符task_struct中的policy字段
3.調(diào)度器中的機(jī)制
內(nèi)核引入調(diào)度類(struct sched_class)說明了調(diào)度器應(yīng)該具有哪些功能。內(nèi)核中每種調(diào)度策略都有該調(diào)度類的一個(gè)實(shí)例。(比如:基于公平調(diào)度類為:fair_sched_class,基于實(shí)時(shí)進(jìn)程的調(diào)度類實(shí)例為:rt_sched_class),該實(shí)例也是針對(duì)每種調(diào)度策略的具體實(shí)現(xiàn)。調(diào)度類封裝了不同調(diào)度策略的具體實(shí)現(xiàn),屏蔽了各種調(diào)度策略的細(xì)節(jié)實(shí)現(xiàn)。
調(diào)度器核心函數(shù)schedule()只需要調(diào)用調(diào)度類中的接口,完成進(jìn)程的調(diào)度,完全不需要考慮調(diào)度策略的具體實(shí)現(xiàn)。調(diào)度類連接了調(diào)度函數(shù)和具體的調(diào)度策略。
武特師兄關(guān)于sche_class和sche_entity的解釋,一語中的。
調(diào)度類就是代表的各種調(diào)度策略,調(diào)度實(shí)體就是調(diào)度單位,這個(gè)實(shí)體通常是一個(gè)進(jìn)程,但是自從引入了cgroup后,這個(gè)調(diào)度實(shí)體可能就不是一個(gè)進(jìn)程了,而是一個(gè)組
4.schedule()函數(shù)
linux 支持兩種類型的進(jìn)程調(diào)度,實(shí)時(shí)進(jìn)程和普通進(jìn)程。實(shí)時(shí)進(jìn)程采用SCHED_FIFO 和SCHED_RR調(diào)度策略,普通進(jìn)程采用SCHED_NORMAL策略。
preempt_disable():禁止內(nèi)核搶占
cpu_rq():獲取當(dāng)前cpu對(duì)應(yīng)的就緒隊(duì)列。
prev = rq-curr;獲取當(dāng)前進(jìn)程的描述符prev
switch_count = prev-nivcsw;獲取當(dāng)前進(jìn)程的切換次數(shù)。
update_rq_clock() :更新就緒隊(duì)列上的時(shí)鐘
clear_tsk_need_resched()清楚當(dāng)前進(jìn)程prev的重新調(diào)度標(biāo)志。
deactive_task():將當(dāng)前進(jìn)程從就緒隊(duì)列中刪除。
put_prev_task() :將當(dāng)前進(jìn)程重新放入就緒隊(duì)列
pick_next_task():在就緒隊(duì)列中挑選下一個(gè)將被執(zhí)行的進(jìn)程。
context_switch():進(jìn)行prev和next兩個(gè)進(jìn)程的切換。具體的切換代碼與體系架構(gòu)有關(guān),在switch_to()中通過一段匯編代碼實(shí)現(xiàn)。
post_schedule():進(jìn)行進(jìn)程切換后的后期處理工作。
5.pick_next_task函數(shù)
選擇下一個(gè)將要被執(zhí)行的進(jìn)程無疑是一個(gè)很重要的過程,我們來看一下內(nèi)核中代碼的實(shí)現(xiàn)
對(duì)以下這段代碼說明:
1.當(dāng)rq中的運(yùn)行隊(duì)列的個(gè)數(shù)(nr_running)和cfs中的nr_runing相等的時(shí)候,表示現(xiàn)在所有的都是普通進(jìn)程,這時(shí)候就會(huì)調(diào)用cfs算法中的pick_next_task(其實(shí)是pick_next_task_fair函數(shù)),當(dāng)不相等的時(shí)候,則調(diào)用sched_class_highest(這是一個(gè)宏,指向的是實(shí)時(shí)進(jìn)程),這下面的這個(gè)for(;;)循環(huán)中,首先是會(huì)在實(shí)時(shí)進(jìn)程中選取要調(diào)度的程序(p = class-pick_next_task(rq);)。如果沒有選取到,會(huì)執(zhí)行class=class-next;在class這個(gè)鏈表中有三種類型(fair,idle,rt).也就是說會(huì)調(diào)用到下一個(gè)調(diào)度類。
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:
*///基于公平調(diào)度的普通進(jìn)程
if (likely(rq-nr_running == rq-cfs.nr_running)) {
?p = fair_sched_class.pick_next_task(rq); ? ? ? ?if (likely(p)) ? ? ? ? ? ?return p;
}//基于實(shí)時(shí)調(diào)度的實(shí)時(shí)進(jìn)程
class = sched_class_highest; ? ?for ( ; ; ) {
?p = class-pick_next_task(rq); ?//實(shí)時(shí)進(jìn)程的類
?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
}
}
在這段代碼中體現(xiàn)了Linux所支持的兩種類型的進(jìn)程,實(shí)時(shí)進(jìn)程和普通進(jìn)程。回顧下:實(shí)時(shí)進(jìn)程可以采用SCHED_FIFO 和SCHED_RR調(diào)度策略,普通進(jìn)程采用SCHED_NORMAL調(diào)度策略。
在這里首先說明一個(gè)結(jié)構(gòu)體struct rq,這個(gè)結(jié)構(gòu)體是調(diào)度器管理可運(yùn)行狀態(tài)進(jìn)程的最主要的數(shù)據(jù)結(jié)構(gòu)。每個(gè)cpu上都有一個(gè)可運(yùn)行的就緒隊(duì)列。剛才在pick_next_task函數(shù)中看到了在選擇下一個(gè)將要被執(zhí)行的進(jìn)程時(shí)實(shí)際上用的是struct rq上的普通進(jìn)程的調(diào)度或者實(shí)時(shí)進(jìn)程的調(diào)度,那么具體是如何調(diào)度的呢?在實(shí)時(shí)調(diào)度中,為了實(shí)現(xiàn)O(1)的調(diào)度算法,內(nèi)核為每個(gè)優(yōu)先級(jí)維護(hù)一個(gè)運(yùn)行隊(duì)列和一個(gè)DECLARE_BITMAP,內(nèi)核根據(jù)DECLARE_BITMAP的bit數(shù)值找出非空的最高級(jí)優(yōu)先隊(duì)列的編號(hào),從而可以從非空的最高級(jí)優(yōu)先隊(duì)列中取出進(jìn)程進(jìn)行運(yùn)行。
我們來看下內(nèi)核的實(shí)現(xiàn)
struct rt_prio_array {
DECLARE_BITMAP(bitmap, MAX_RT_PRIO+1); /* include 1 bit for delimiter */
struct list_head queue[MAX_RT_PRIO];
};
數(shù)組queue[i]里面存放的是優(yōu)先級(jí)為i的進(jìn)程隊(duì)列的鏈表頭。在結(jié)構(gòu)體rt_prio_array 中有一個(gè)重要的數(shù)據(jù)構(gòu)DECLARE_BITMAP,它在內(nèi)核中的第一如下:
define DECLARE_BITMAP(name,bits) \
unsigned long name[BITS_TO_LONGS(bits)]
5.1對(duì)于實(shí)時(shí)進(jìn)程的O(1)算法
這個(gè)數(shù)據(jù)是用來作為進(jìn)程隊(duì)列queue[MAX_PRIO]的索引位圖。bitmap中的每一位與queue[i]對(duì)應(yīng),當(dāng)queue[i]的進(jìn)程隊(duì)列不為空時(shí),Bitmap的相應(yīng)位就為1,否則為0,這樣就只需要通過匯編指令從進(jìn)程優(yōu)先級(jí)由高到低的方向找到第一個(gè)為1的位置,則這個(gè)位置就是就緒隊(duì)列中最高的優(yōu)先級(jí)(函數(shù)sched_find_first_bit()就是用來實(shí)現(xiàn)該目的的)。那么queue[index]-next就是要找的候選進(jìn)程。
如果還是不懂,那就來看兩個(gè)圖
注:在每個(gè)隊(duì)列上的任務(wù)一般基于先進(jìn)先出的原則進(jìn)行調(diào)度(并且為每個(gè)進(jìn)程分配時(shí)間片)
在內(nèi)核中的實(shí)現(xiàn)為:
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); //找到優(yōu)先級(jí)最高的位
BUG_ON(idx = MAX_RT_PRIO); ? ?queue = array-queue + idx; //然后找到對(duì)應(yīng)的queue的起始地址
next = list_entry(queue-next, struct sched_rt_entity, run_list); ?//按先進(jìn)先出拿任務(wù)
return next;
}
那么當(dāng)同一優(yōu)先級(jí)的任務(wù)比較多的時(shí)候,內(nèi)核會(huì)根據(jù)
位圖:
將對(duì)應(yīng)的位置為1,每次取出最大的被置為1的位,表示優(yōu)先級(jí)最高:
5.2 關(guān)于普通進(jìn)程的CFS算法:
我們知道,普通進(jìn)程在選取下一個(gè)需要被調(diào)度的進(jìn)程時(shí),是調(diào)用的pick_next_task_fair函數(shù)。在這個(gè)函數(shù)中是以調(diào)度實(shí)體為單位進(jìn)行調(diào)度的。其最主要的函數(shù)是:pick_next_entity,在這個(gè)函數(shù)中會(huì)調(diào)用wakeup_preempt_entity函數(shù),這個(gè)函數(shù)的主要作用是根據(jù)進(jìn)程的虛擬時(shí)間以及權(quán)重的結(jié)算進(jìn)程的粒度,以判斷其是否需要搶占。看一下內(nèi)核是怎么實(shí)現(xiàn)的:
wakeup_preempt_entity(struct sched_entity *curr, struct sched_entity *se)
{
s64 gran, vdiff = curr-vruntime - se-vruntime;//計(jì)算兩個(gè)虛擬時(shí)間差//如果se的虛擬時(shí)間比curr還大,說明本該curr執(zhí)行,無需搶占
if (vdiff = 0) ? ? ? ?return -1;
gran = wakeup_gran(curr, se); ? ?if (vdiff gran) ? ? ? ?return 1; ? ?return 0;
}
gran為需要搶占的時(shí)間差,只有兩個(gè)時(shí)間差大于需要搶占的時(shí)間差,才需要搶占,這里避免太頻繁的搶占
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.調(diào)度中的nice值
首先需要明確的是:nice的值不是進(jìn)程的優(yōu)先級(jí),他們不是一個(gè)概念,但是進(jìn)程的Nice值會(huì)影響到進(jìn)程的優(yōu)先級(jí)的變化。
通過命令ps -el可以看到進(jìn)程的nice值為NI列。PRI表示的是進(jìn)程的優(yōu)先級(jí),其實(shí)進(jìn)程的優(yōu)先級(jí)只是一個(gè)整數(shù),它是調(diào)度器選擇進(jìn)程運(yùn)行的基礎(chǔ)。
普通進(jìn)程有:靜態(tài)優(yōu)先級(jí)和動(dòng)態(tài)優(yōu)先級(jí)。
靜態(tài)優(yōu)先級(jí):之所有稱為靜態(tài)優(yōu)先級(jí)是因?yàn)樗粫?huì)隨著時(shí)間而改變,內(nèi)核不會(huì)修改它,只能通過系統(tǒng)調(diào)用nice去修改,靜態(tài)優(yōu)先級(jí)用進(jìn)程描述符中的static_prio來表示。在內(nèi)核中/kernel/sched.c中,nice和靜態(tài)優(yōu)先級(jí)的關(guān)系為:
#define NICE_TO_PRIO(nice) ?(MAX_RT_PRIO + (nice) + 20)
#define PRIO_TO_NICE(prio) ?((prio) - MAX_RT_PRIO - 20)
動(dòng)態(tài)優(yōu)先級(jí):調(diào)度程序通過增加或者減小進(jìn)程靜態(tài)優(yōu)先級(jí)的值來獎(jiǎng)勵(lì)I(lǐng)O小的進(jìn)程或者懲罰cpu消耗型的進(jìn)程。調(diào)整后的優(yōu)先級(jí)稱為動(dòng)態(tài)優(yōu)先級(jí)。在進(jìn)程描述中用prio來表示,通常所說的優(yōu)先級(jí)指的是動(dòng)態(tài)優(yōu)先級(jí)。
由上面分析可知,我們可以通過系統(tǒng)調(diào)用nice函數(shù)來改變進(jìn)程的優(yōu)先級(jí)。
#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)))//做一個(gè)延遲的計(jì)算double do_something (void){ ? ?int j; ? ?double x = 0.0; ? ?struct timeval tv1, tv2;
gettimeofday (tv1, NULL);//獲取時(shí)區(qū)
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);//讀取進(jìn)程的調(diào)度狀態(tài)
/*
?在schedstat中的數(shù)字是什么意思呢?:
*/
/* ? ?printf ("Fname = %s\n", fname); */
if (!(fp = fopen (fname, "r"))) { ? ? ? ?printf ("Failed to open stat file\n"); ? ? ? ?exit (-1);
} ? ?//nice系統(tǒng)調(diào)用
if (nice (niceval) == -1 niceval != -1) { ? ? ? ?printf ("Failed to set nice to %d\n", niceval); ? ? ? ?exit (-1);
}
elapsed_time = do_something ();//for 循環(huán)執(zhí)行了多長(zhǎng)時(shí)間
fscanf (fp, "%ld %ld %d", ticks_cpu, ticks_sleep, nsched);//nsched表示調(diào)度的次數(shù)
t_cpu = (float)ticks_cpu / scale;//震動(dòng)的次數(shù)除以1000,就是時(shí)間
t_sleep = (float)ticks_sleep / scale;
timeslice = t_cpu / (double)nsched;//除以調(diào)度的次數(shù),就是每次調(diào)度的時(shí)間(時(shí)間片)
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:在這個(gè)文件下放著3個(gè)變量,他們分別代表什么意思呢?
第一個(gè):該進(jìn)程擁有的cpu的時(shí)間
第二個(gè):在對(duì)列上的等待時(shí)間,即睡眠時(shí)間
第三個(gè):被調(diào)度的次數(shù)
由結(jié)果可以看出當(dāng)nice的值越小的時(shí)候,其睡眠時(shí)間越短,則表示其優(yōu)先級(jí)升高了。
7.關(guān)于獲取和設(shè)置優(yōu)先級(jí)的系統(tǒng)調(diào)用: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 */
//獲取進(jìn)程調(diào)度的策略
policy = sched_getscheduler (0);
printpolicy (policy); ? ?/* reset scheduling policy */
printf ("\nTrying sched_setscheduler...\n");
policy = SCHED_FIFO;
printpolicy (policy);
p.sched_priority = 50; ? ?//設(shè)置優(yōu)先級(jí)為50
if (sched_setscheduler (0, policy, p))
?DEATH ("sched_setscheduler:"); ? ?printf ("p.sched_priority = %d\n", p.sched_priority); ? ?exit (0);
}
輸出結(jié)果:
[root@wang schedule]# ./get_schedule_policy policy = SCHED_OTHER = 0
Trying sched_setscheduler...
policy = SCHED_FIFO = 1
p.sched_priority = 50
可以看出進(jìn)程的優(yōu)先級(jí)已經(jīng)被改變。
任務(wù)調(diào)度的crond常駐命令
crond 是linux用來定期執(zhí)行程序的命令。當(dāng)安裝完成操作系統(tǒng)之后,默認(rèn)便會(huì)啟動(dòng)此任務(wù)調(diào)度命令。crond命令每分鍾會(huì)定期檢查是否有要執(zhí)行的工作,如果有要執(zhí)行的工作便會(huì)自動(dòng)執(zhí)行該工作。而linux任務(wù)調(diào)度的工作主要分為以下兩類:
1、系統(tǒng)執(zhí)行的工作:系統(tǒng)周期性所要執(zhí)行的工作,如備份系統(tǒng)數(shù)據(jù)、清理緩存
2、個(gè)人執(zhí)行的工作:某個(gè)用戶定期要做的工作,例如每隔10分鐘檢查郵件服務(wù)器是否有新信,這些工作可由每個(gè)用戶自行設(shè)置
Crontab是UNIX系統(tǒng)下的定時(shí)任務(wù)觸發(fā)器,其使用者的權(quán)限記載在下列兩個(gè)文件中:
文件
含義
/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],其參數(shù)含義如表一:
參數(shù)名稱
含義
示例
-l
顯示用戶的Crontab文件的內(nèi)容
crontabl –l
-i
刪除用戶的Crontab文件前給提示
crontabl -ri
-r
從Crontab目錄中刪除用戶的Crontab文件
crontabl -r
-e
編輯用戶的Crontab文件
crontabl -e
用戶所建立的Crontab文件存于/var/spool/cron中,其文件名與用戶名一致。
它的格式共分為六段,前五段為時(shí)間設(shè)定段,第六段為所要執(zhí)行的命令段,
格式如下:* * * * *
其時(shí)間段的含義如表二:
段
含義
取值范圍
第一段
代表分鐘
0—59
第二段
代表小時(shí)
0—23
第三段
代表日期
1—31
第四段
代表月份
1—12
第五段
代表星期幾,0代表星期日
0—6
例:如果用戶的Crontab文件的內(nèi)容是:29 19 * * * echo its dinner time,則系統(tǒng)每天的19:29顯示‘its dinner time’
示例(創(chuàng)建一個(gè)cron全過程,每分鐘都會(huì)在test.txt里輸入當(dāng)前時(shí)間):
1. 以普通用戶登錄linux系統(tǒng)(我用的是CentOS4.1)
2. $crontab –e
說明:系統(tǒng)默認(rèn)的編輯器是VIM,如果不是請(qǐng)加上以下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
下面看看看幾個(gè)具體的例子:
● 0 */2 * * * /sbin/service httpd restart 意思是每?jī)蓚€(gè)小時(shí)重啟一次apache
● 50 7 * * * /sbin/service sshd start 意思是每天7:50開啟ssh服務(wù)
● 50 22 * * * /sbin/service sshd stop 意思是每天22:50關(guān)閉ssh服務(wù)
● 0 0 1,15 * * fsck /home 每月1號(hào)和15號(hào)檢查/home 磁盤
● 1 * * * * /home/bruce/backup 每小時(shí)的第一分執(zhí)行 /home/bruce/backup這個(gè)文件
● 00 03 * * 1-5 find /home "*.xxx" -mtime +4 -exec rm {} /; 每周一至周五3點(diǎn)鐘,在目錄/home中,查找文件名為*.xxx的文件,并刪除4天前的文件。
● 30 6 */10 * * ls 意思是每月的1、11、21、31日是的6:30執(zhí)行一次ls命令
參數(shù) :
crontab -e : 執(zhí)行文字編輯器來設(shè)定時(shí)程表,內(nèi)定的文字編輯器是 VI,如果你想用別的文字編輯器,則請(qǐng)先設(shè)定 VISUAL 環(huán)境變數(shù)來指定使用那個(gè)文字編輯器(比如說 setenv VISUAL joe)
crontab -r : 刪除目前的時(shí)程表
crontab -l : 列出目前的時(shí)程表
crontab file [-u user]-用指定的文件替代目前的crontab。
時(shí)程表的格式如下 :
f1 f2 f3 f4 f5 program
其中 f1 是表示分鐘,f2 表示小時(shí),f3 表示一個(gè)月份中的第幾日,f4 表示月份,f5 表示一個(gè)星期中的第幾天。program 表示要執(zhí)行的程序。
當(dāng) f1 為 * 時(shí)表示每分鐘都要執(zhí)行 program,f2 為 * 時(shí)表示每小時(shí)都要執(zhí)行程序,其馀類推
當(dāng) f1 為 a-b 時(shí)表示從第 a 分鐘到第 b 分鐘這段時(shí)間內(nèi)要執(zhí)行,f2 為 a-b 時(shí)表示從第 a 到第 b 小時(shí)都要執(zhí)行,其馀類推
當(dāng) f1 為 */n 時(shí)表示每 n 分鐘個(gè)時(shí)間間隔執(zhí)行一次,f2 為 */n 表示每 n 小時(shí)個(gè)時(shí)間間隔執(zhí)行一次,其馀類推
當(dāng) f1 為 a, b, c,... 時(shí)表示第 a, b, c,... 分鐘要執(zhí)行,f2 為 a, b, c,... 時(shí)表示第 a, b, c...個(gè)小時(shí)要執(zhí)行,其馀類推
使用者也可以將所有的設(shè)定先存放在檔案 file 中,用 crontab file 的方式來設(shè)定時(shí)程表。
crontab執(zhí)行java程序的問題:
一 crontab使用注意:
crontab -l查看該用戶的crontab配置,crontab -e編輯該用戶的crontab配置配置一般在末尾加上 21表示錯(cuò)誤輸出(2)和標(biāo)準(zhǔn)輸出(1)一樣輸出到同一個(gè)由前面指定的地方
如 15 14 * * * /sys_back/monitor.sh /sys_back/log/monitor.log 21
表示每天14:15執(zhí)行monitor.sh腳本,錯(cuò)誤和標(biāo)準(zhǔn)輸出都寫入monitor.log文件
涉及到文件名時(shí)最好寫絕對(duì)路徑
二 問題及解決
shell腳本有echo語句,有java -jar執(zhí)行java程序。直接執(zhí)行腳本時(shí),一切順利,但是放到crontab中執(zhí)行時(shí),echo語句正常,java程序卻沒有執(zhí)行。
1 網(wǎng)上查找,覺得應(yīng)該是環(huán)境變量的問題。說是要將java環(huán)境變量加入到shell腳本中,按照
這個(gè)方法做,發(fā)現(xiàn)問題依然存在。百思不得其解。
2 經(jīng)轉(zhuǎn)換角度,看java程序是否有問題。在java語句中直接加入打印語句,發(fā)現(xiàn)其在crontab日志中
居然可以顯示。終于確定是java程序的問題。java程序功能很簡(jiǎn)單,就是一個(gè)語句java -Dosgi.console -Dosgi.configuration.area=./configuration -jar equinox.jar -console用來啟動(dòng)osgi框架。
于是在shell腳本中不調(diào)用java程序,直接改為程序中的這一句,問題解決。
但是又引發(fā)新的問題:直接java -jar會(huì)源源不斷的輸出osgi到日志文件,導(dǎo)致日志文件越來越大。
不可行。再想辦法解決。
3 感覺還是相對(duì)路徑的問題。嘗試在crontab調(diào)用的腳本中用相對(duì)路徑向一個(gè)文件輸出一句話,發(fā)現(xiàn)失敗。(單獨(dú)執(zhí)行腳本沒問題)既然如此,是不是java程序中也不能用相對(duì)路徑呢。遂將./configuration及equinox.jar都用絕對(duì)路徑,再調(diào)試,終于成功,至此問題解決。但始終感覺在程序中用絕對(duì)路徑很不方便維護(hù)。
三 附加問題及解決
此腳本的作用就是判斷osgi程序是否在運(yùn)行,如果不運(yùn)行則啟動(dòng)。
實(shí)現(xiàn)思路是ps -elf得到進(jìn)程id及狀態(tài),如果id不存在,則啟動(dòng),如果id存在但狀態(tài)不是運(yùn)行中(solaris為O,AIX為A),則殺掉原進(jìn)程重新啟動(dòng)。
發(fā)現(xiàn)程序在運(yùn)行幾天后會(huì)自動(dòng)停掉,以為是java程序有問題,然而卻始終找不到問題在哪里。在解決上面問題時(shí),卻意外的發(fā)現(xiàn)可能不是java程序的問題。man ps時(shí)發(fā)現(xiàn),solaris中,進(jìn)程狀態(tài)除了O,還有S(sleeping) R(Runnable) Z(Zombie僵尸進(jìn)程)T(stopped),只有后兩種狀態(tài)下進(jìn)程才是有問題的,所以很可能是crontab執(zhí)行腳本時(shí),程序狀態(tài)非O就被殺掉,重啟時(shí)卻因?yàn)樯厦娴膯栴}沒成功。于是修改腳本,狀態(tài)是后兩種時(shí)才重啟。這個(gè)問題也解決了。
我也是網(wǎng)上轉(zhuǎn)的,望采納
先說下$和#在linux系統(tǒng)終端(命令行)中通常代表的什么: $打頭的表示這不是在root用戶(管理員用戶)下執(zhí)行的命令 #打頭的和前者相反,即root用戶下 再說如何使$變?yōu)?? 即在命令行中如何切換到root用戶下: $su root 【鍵盤按回車】 輸入root的密碼 如果不知道root的密碼,可以通過重新設(shè)置,但是下面的方法需要知道當(dāng)前用戶的密碼: $sudo passwd root 【鍵盤按回車】 會(huì)提示輸入當(dāng)前用戶的密碼 接著會(huì)提示輸入root的新密碼 最后確認(rèn)新密碼 希望能幫到你,歡迎來到linux的世界。 不明白可以追問。
一,使用taskset充分利用多核cpu,讓cpu的使用率均衡到每個(gè)cpu上
#taskset
-p, 設(shè)定一個(gè)已存在的pid,而不是重新開啟一個(gè)新任務(wù)
-c, 指定一個(gè)處理,可以指定多個(gè),以逗號(hào)分隔,也可指定范圍,如:2,4,5,6-8。
1,切換某個(gè)進(jìn)程到指定的cpu上
taskset -cp 3 13290
2,讓某程序運(yùn)行在指定的cpu上
taskset -c 1,2,4-7 tar jcf test.tar.gz test
需要注意的是,taskset -cp 3 13290在設(shè)定一個(gè)已經(jīng)存在的pid時(shí),子進(jìn)程并不會(huì)繼承父進(jìn)程的,
因此像tar zcf xxx.tar.gz xxx這樣的命令,最好在啟動(dòng)時(shí)指定cpu,如果在已經(jīng)啟動(dòng)的情況下,則需要指定tar調(diào)用的gzip進(jìn)程。
二,使用nice和renice設(shè)置程序執(zhí)行的優(yōu)先級(jí)
格式:nice [-n 數(shù)值] 命令
nice 指令可以改變程序執(zhí)行的優(yōu)先權(quán)等級(jí)。指令讓使用者在執(zhí)行程序時(shí),指定一個(gè)優(yōu)先等級(jí),稱之為 nice 值。
這個(gè)數(shù)值從最高優(yōu)先級(jí)的-20到最低優(yōu)先級(jí)的19。負(fù)數(shù)值只有 root 才有權(quán)力使。
一般使用者,也可使用 nice 指令來做執(zhí)行程序的優(yōu)先級(jí)管理,但只能將nice值越調(diào)越高。
可以通過二種方式來給某個(gè)程序設(shè)定nice值:
1,開始執(zhí)行程序時(shí)給定一個(gè)nice值,用nice命令
2,調(diào)整某個(gè)運(yùn)行中程序的PID的nice值,用renice命令
通常通過調(diào)高nice值來備份,為的是不占用非常多的系統(tǒng)資源。
例:
nice -n 10 tar zcf test.tar.gz test
由nice啟動(dòng)的程序,其子進(jìn)程會(huì)繼承父進(jìn)程的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調(diào)整運(yùn)行中程序的nice值
格式:renice [nice值] PID
三,使用ulimit限制cpu占用時(shí)間
注意,ulimit 限制的是當(dāng)前shell進(jìn)程以及其派生的子進(jìn)程。因此可以在腳本中調(diào)用ulimit來限制cpu使用時(shí)間。
例如,限制tar的cpu占用時(shí)間,單位秒。
# cat limit_cpu.sh
ulimit -SHt 100
tar test.tar.gz test
如果tar占用時(shí)間超過了100秒,tar將會(huì)退出,這可能會(huì)導(dǎo)致打包不完全,因此不推薦使用ulimit對(duì)cpu占用時(shí)間進(jìn)行限制。
另外,通過修改系統(tǒng)的/etc/security/limits配置文件,可以針對(duì)用戶進(jìn)行限制。
四,使用程序自帶的對(duì)cpu使用調(diào)整的功能
某些程序自帶了對(duì)cpu使用調(diào)整的功能,比如nginx服務(wù)器,通過其配置文件,可以為工作進(jìn)程指定cpu,如下:
worker_processes 3;
worker_cpu_affinity 0001 0010 0100 1000;
這里0001 0010 0100 1000是掩碼,分別代表第1、2、3、4顆cpu核心,這就使得cpu的使用比較平均到每個(gè)核心上。
網(wǎng)頁名稱:linux調(diào)度命令 linux調(diào)度方式
文章地址:http://www.rwnh.cn/article46/doohihg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供網(wǎng)站設(shè)計(jì)、品牌網(wǎng)站制作、App設(shè)計(jì)、手機(jī)網(wǎng)站建設(shè)、外貿(mào)網(wǎng)站建設(shè)、全網(wǎng)營(yíng)銷推廣
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來源: 創(chuàng)新互聯(lián)