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