進程監控源碼
Ⅰ linux下如何監聽進程
一、supervise
Supervise是daemontools的一個工具,可以用來監控管理unix下的應用程序運行情況,在應用程序出現異常時,supervise可以重新啟動指定程序。
使用:
mkdir test
cd test
vim run 寫入希望執行的操作
supervise test (注意這里是的參數是run文件上層的文件夾,改變run的為可執行 chmod +x run)
二、monit
monit是一個小型的開放源碼工具來管理和監控Unix系統。Monit可以自動維護進程,及時避免進程異常退出等產生的問題。
系統: monit可以監控問題的發生,包括進程狀態、系統cpu負載、內存佔用情況等,例如當apache服務的cpu負載以及內存閘弄情況過高時候,它會重啟apache服務。
進程: monit可以監控守護進程,包括系統進程。例如當某個進行down掉,它會自動恢復重啟該進程。
文件系統:Monit可以監控本地文件、目錄、文件系統的變化,包括時間戳、校驗值、大小的變化。例如,可以監控文件sha1以及md5的值,來監控文件是否發生變化。
網路:monit可以監控網路連接,支持TCP、UDP、Unix domain sockets以及HTTP、SMTP等。
定時腳本:monit可以用來定時測試程序和腳本,獲取程序輸出結果,進而判斷是否成功或其他情況。
安裝:
sudo apt-get install monit
編輯配置:
sudo vim /etc/monit/monitrc
啟動、停止、重啟:
sudo /etc/init.d/monit start
sudo /etc/init.d/monit stop
sudo /etc/init.d/monit restart
設置頁面監控狀態:
set httpd port 2812 and
allow 0.0.0.0/0.0.0.0
allow localhost
增加監控:
需要注意的是,這里需要添加start和stop,缺一個都是不行的
1.根據程序名稱來監控
check process test with MATCHING test.py
start program = "/home/yxd/test.py"
stop program = "xxxxx"
2.根據pid監控
check process apache with pidfile /var/run/httpd.pid
start program = "/etc/init.d/rcWebServer.sh start https"
stop program = "/etc/init.d/rcWebServer.sh stop https"
if changed pid then aler
參考:用monit監控系統關鍵進程
supervisord
Supervisor是一個C/S系統,它可以在類unix操作系統讓用戶來監視和控制後台服務進程的數量。它是由python編寫的,常用於進程異常退出的重啟保護。
安裝:
pip install supervisor
查看配置文件:
echo_supervisord_conf
從該命令的結果中,可以看到各個模塊的配置信息。
創建配置文件:
echo_supervisord_conf > /etc/supervisord.conf
配置應用:
[program:test]
command=python /root/test_supervisor.py
process_name=%(program_name)s
stdout_logfile=/root/test.log
stderr_logfile=/root/test.log
保存,啟動:
/usr/bin/supervisord -c /etc/supervisord.conf
Ⅱ linux下監控進程是否掛掉的一種方法
所以,有時候對進程進行實時監控,當發現進程掛掉時,立刻重新啟動進程,也是一種可以救急的方式(當然這個只是一種臨時救急,並不是根本解決方法)。
實現方式:使用fork()創建子進程,子進程用於執行具體功能,主進程只是用於監控子進程,當主進程檢測到子進程掛掉後,可以實現立即重新啟動子進程。
子進程結束,系統會向主進程發送信號:SIGCHLD,主進程可以通過捕捉該信號,從而檢測子進程已經不存在,進而繼續下一步操作。如果需要,主進程還可以獲得子進程是為何退出的。
源代碼例子:#include#include#include#include#include#include#includevoid process_exit(int s){exit(0);}void child_fun(){printf("child_fun. ppid %d\n",getppid());
char *st = NULL;
strcpy(st, "123");}void fork_child(){pid_t child_process;
int status;
int signal_num;
wait(&status);//等待子進程中斷或終止,釋放子進程資源,否則死掉的子進程會變成僵屍進程
//如果子進程是由於某種信號退出的,捕獲該信號
if(WIFSIGNALED(status))
signal_num = WTERMSIG(status);
child_process = fork();
if(child_process == 0){printf("fork new child process.\n");
child_fun();}}int main(){pid_t child_process;int i = 0;while(1){printf("fork new process.\n");
child_process = fork();
if(child_process > 0){while(1){//捕獲子進程結束信號
signal(SIGCHLD, fork_child);
signal(SIGTERM, process_exit);
pause();//主進程休眠,當有信號到來時被喚醒。}}else if(child_process == 0){child_fun();}}return 0;}僵屍進程的產生:
在fork()/execve()過程中,假設子進程結束時父進程仍存在,而父進程如果沒有給子進程收屍,死掉的子進程就變成僵屍進程了。僵屍進程是非常特殊的一種,它已經放棄了幾乎所有內存空間,沒有任何可執行代碼,也不能被調度,僅僅在進程列表中保留一個位置,記載該進程的退出狀態等信息供其他進程收集,除此之外,僵屍進程不再佔有任何內存空間,它需要它的父進程來為它收屍。僵屍進程,無法正常結束,此時即使是root身份kill-9也不能殺死僵屍進程。補救辦法是殺死僵屍進程的父進程(僵屍進程的父進程必然存在),僵屍進程成為"孤兒進程",過繼給1號進程init,init始終會負責清理僵屍進程。
僵屍進程的危害:
Linux系統對運行的進程數量有限制,如果產生過多的僵屍進程佔用了可用的進程號,將會導致新的進程無法生成。這就是僵屍進程對系統的最大危害。
Ⅲ 易語言,結束進程線程源碼
什麼意思?結束進程就這樣結束啊終止進程(「某某進程.exe")
Ⅳ 如何查看linux進程的源代碼,注意是進程
具體來說呢?
進程調度是kernel/sched.c,進程在內存中的數據結構定義在linux/sched.h
Ⅳ C++中怎麼監控進程本人C++小白,迫於特殊原因,求各位幫個忙!
實現代碼如下,代碼在vs2013和vs2017都通過測試:
#include"stdafx.h"
#include<windows.h>
#include<Tlhelp32.h>
intmain(intargc,char*argv[])
{
while(true){
HANDLEhSnapshot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
if(INVALID_HANDLE_VALUE==hSnapshot)
{
return0;
}
PROCESSENTRY32pi;
pi.dwSize=sizeof(PROCESSENTRY32);
BOOLbRet=Process32First(hSnapshot,&pi);
boolw1=false;
boolw2=false;
while(bRet)
{
if(!wcscmp(L"watch.exe",pi.szExeFile)){
w1=true;
}
elseif(!wcscmp(L"asker.exe",pi.szExeFile)){
w2=true;
}
bRet=Process32Next(hSnapshot,&pi);
}
if(!w1){
WinExec("C://windows//watch.exe",SW_SHOWMAXIMIZED);
}
if(!w2){
WinExec("C://windows//asker.exe",SW_SHOWMAXIMIZED);
}
Sleep(3000);
}
return0;
}
Ⅵ 易語言怎麼做視頻監控求源碼!QAQ
首先,易語言高!成千上萬的源碼可以借鑒!
其次夠底層,直接嵌入匯編!用上黑月插件,編譯夠小!
易語言的獨特模塊,拿來就用!
_
破解,病毒,游戲輔助,基本都是在反編譯,掌握了程序基本情況之後,在寫程序!!
寫內存,讀內存,進程注入,這些技術在其他編程語言實現你的看各種文檔! 而易語言,各種注入模塊,驅動讀寫內存,都是現成的!
而其他語言,如c語言,你寫的時候,很多時間,都是在了解c的各種庫。本來你只想吃饅頭,用c你就得了解包頭的烹飪方法!如果,你還需要互動的界面的話......成本太高了!
易語言很多時候其實只是負責UI,很多動態庫都是其他語言編寫的,易語言負責調用整合!
可以說,易語言,在開發小程序,有天然的優勢!
Ⅶ 求: 用c語言實現進程式控制制的源碼
createthread(...)等等有一系列windowsAPI
你願意用嗎?
pv操作是利用信號量等的變數實現的,也有專門的api函數用於操作信號量等
Ⅷ php 後台怎麼開一個進程監聽Redis的隊列消息呢用while
redis的subscribe用pconnect鏈接,執行這個腳本的進程會自動監聽所訂閱的頻道發送的消息
ini_set(『default_socket_timeout』, -1);
$redis = new \Redis();
$redis->pconnect('127.0.0.1', 6379);
//訂閱
$redis->subscribe(['msg'], 'callfun');
function callfun($redis, $channel, $msg)
{
var_mp([
'redis' => $redis,
'channel' => $channel,
'msg' => $msg
]);
}
Ⅸ 易語言怎麼寫監視進程,最好就用超級模塊寫例子!
.版本 2
.子程序 __啟動窗口_創建完畢
.如果 (進程是否存在 (「1.exe」) = 真)
信息框 (「該文件存在,已暫停!」, 0, )
.否則
信息框 (「該文件不存在,正常運行!」, 0, )
.如果結束
Ⅹ windows 進程管理源代碼詳解,要詳細的,
Windows 是閉源開發的商業軟體,受商業版權法保護,別說大家都沒有,就算有也不能給你的(被微軟起訴那可不是小事)。
Linux的是開源的,幹嘛不去讀Linux源碼呢?
新版本的太長,寫不開,給你最經典的0.11版的進程管理源碼。其他的你自己去查。作為一個好的程序員,必須學會充分利用搜索引擎。
---------------------------------------
linux0.11通過一個進程數組管理進程,最大允許64個進程存在。進程的狀態有就緒態,運行態,暫停態,睡眠態和僵死態等。睡眠態又可分為可中斷和不可中斷兩種。對於進程的管理,我覺得按照進程的狀態來講會清晰一些。
1.0號任務
0號比較特殊,是"純手工製作",下面就是製作過程
mem_init(main_memory_start,memory_end);
trap_init();
blk_dev_init();
char_dev_init();
tty_init();
time_init();
sched_init();
buffer_init(buffer_memory_end);
hd_init();
floppy_init();
sti();
move_to_user_mode();
這么多init當然不全是為0任務准備的,他們是初始化系統。對任務0來說,重要的是sched_init()和move_to_user_mode()兩個。sched_init()中手動設置了任務0的任務段描述符tss和局部段描述符ldt,並設置了tr和ldtr寄存器:
set_tss_desc(gdt+FIRST_TSS_ENTRY,&(init_task.task.tss)); //設置tss段描述符
set_ldt_desc(gdt+FIRST_LDT_ENTRY,&(init_task.task.ldt));//設置ldt描述符
...
ltr(0); //載入tss描述符地址到tr
lldt(0); //載入ldt描述符地址到ldtr
我們來看一下任務0的tss和ldt是什麼樣子
/*ldt*/ {0,0},\
{0x9f,0xc0fa00},\
{0x9f,0xc0f200},\
/*tss*/{0,PAGE_SIZE+(long)&init_task,0x10,0,0,0,0,(long)&pg_dir,\
0,0,0,0,0,0,0,0,\
0,0,0x17,0x17,0x17,0x17,0x17,0x17,\
_LDT(0),0X80000000,\
{}\
},\
從ldt 可以看到,任務的代碼和數據段均為640k,基址為0,DPL=3。這說明雖然任務0的代碼還是處在內核段內,但是任務的級別已經是用戶態了。從tss也可以看到這一點,代碼和數據都被置為0x17,也就是局部段描述符表第2項。還可以看到任務0的內核太堆棧被設置在init_task之後的一頁處,用戶態堆棧就是move_to_user_mode之前的內核態堆棧。這和普通進程不一樣,普通進程的用戶態堆棧在其64Mb地址空間的末端。
move_to_user_mode是在堆棧中創建一個任務切換的假象,用iret跳轉到外層3,這樣cpu就會自動根據tr載入tss,並初始化各個寄存器運行任務0。所以,任務0其實就是內核空間中的用戶態任務。
2.進程的創建
進程創建是由系統調用sys_fork完成的,主要使用了兩個函數find_empty_process和_process。前者在進程在進程數組中找一個不用的進程號給子進程,後者完成子進程信息的創建,主要是復制父進程的信息。
我們來看一下_process的代碼:
int _process(int nr,long ebp,long edi,long esi,long gs,long none,
long ebx,long ecx,long edx,long fs,long es,long ds,
long eip,long cs,long eflags,long esp,long ss)
{
struct task_struct *p;
int i;
struct file *f;
//首先為子進程的進程描述符分配一塊內存
p=(struct task_struct *)get_free_page();
if(!p)
return -EAGAIN;
//將新任務結構指針加入數組中
task[nr]=p;
//復制當前用戶的任務結構到子進程中。當然堆棧不復制
*p=*current;
//將子進程的狀態設為不可中斷等待,防止現在被調度
p->state=TASK_UNINTERRUPTIBLE;
P->pid=last_pid;
p->father=current->pid;
p->count=p->priority;
p->signal=0;
p->alarm=0;
p->leader=0;
p->utime=p->stime=0;
p->cutime=p->cstime=0;
p->start_time=jiffies;
p->tss.back_link=0;
//新進程的內核態堆棧在進程描述符頁末端
p->tss.esp0=PAGE_SIZE+(long)p;
P->tss.ss0=0x10;
//ip為父進程調用fork的下一條指令
p->tss.eip=eip;
//fork的返回值對子進程來說是0,對父進程來說是它的pid,通過這個區別,在fork調用返回後,父子進程的代碼段便被分割來,
p->tss.eax=0;
//雖然他們是在一個代碼文件中寫的
p->tss.ecx=ecx;
p->tss.edx=edx;
p->tss.ebx=ebx;
p->tss.esp=esp;
p->tss.ebp=ebp;
p->tss.esi=esi;
p->tss.edi=edi;
p->tss.es=es&0xffff;
p->tss.cs=cs&0xffff;
p->tss.ss=ss&0xffff;
p->tss.ds=ds&0xffff;
p->tss.fs=fs&0xffff;
p->tss.gs=gs&0xffff;
p->tss.ldt=_LDT(nr);
p->tss.trace_bitmap=0x80000000;
//如果父任務使用了協處理器,還要保存到tss中
if(last_task_used_math==current)
_asm("clts;fnsave %0"::"m"(p->tss.i387));
//為新任務設置新的代碼和數據段基地址。注意,因為linux0.11隻支持64M的進程空間,所以進程的線性地址空間在64M的邊界處。
//然後為新任務復制父進程的頁表。通過_page_tales,父子任務此時共用一個只讀的代碼數據段。在寫操作時,寫時復制會為新進程申請新的物理頁面。
if(_mem(nr,p)){
task[nr]=NULL;
free_page((long)p);
return -EAGAIN;
}
for(i=0;i<NR_OPEN;i++)
if(f=p->filp)
f->f_count++;
if(current->pwd)
current->pwd->i_count++;
if(current->root)
current->root->i_count++;
if(current->executable)
current->executable->i_count++;
//設置新任務的tss和ldt描述符
set_tss_desc(gdt+(nr<<1)+FIRST_TSS_ENTRY,&(p->tss));
set_ldt_desc(gdt+(nr<<1)+FIRST_LDT_ENTRY,&(p->ldt));
//返回子進程的pid
return last_pid;
}
參數都是堆棧中的值,nr是調用_process之前的find_empty_process的返回值,作為任務數組的序號。
3.進程的調度
進程創建之後並不是立即執行。系統會在適當的時刻調用系統調度函數schele,它會選擇適當的進程運行。調度函數可能在系統調用結束之後,進程暫停/ 睡眠/退出,時鍾中斷等多個地方調用。調度函數主要是通過進程的時間片來選擇一個運行時間最短的進程運行。如果沒有找到就運行空閑pause系統調用,在 Pause中,調度函數又會被調用。下面是主要代碼
while(1){
c=-1;
next=0;
i=NR_TASKS;
p=&task[NR_TASKS];
//尋找就緒任務中運行時間最短的任務
while(--i){
if(!(*--p))
continue;
if((*p)->state==TASK_RUNNING&&(*p)->counter>c)
c=(*p)->counter,next=i;
}
//如果找到,就退出。否則重新計算任務的時間片。注意,如果沒有任務,next始終為0,結果就被切換到任務0
if(c)break;
for(p=&LAST_TASK;p>&FIRST_TASK;--p)
if(*p)
(*p)->counter=((*p)->counter>>1)+(*)->priority;
}
switch_to(next);//通過長跳轉,轉換任務到新任務。
}
時鍾中斷是執行調度的重要措施,正是由於不斷的執行調度,系統才能在多個任務之間進行切換,完成多任務操作系統的目標。在調度器初始化時,除了手動設置了任務0,還對8253開啟了定時器中斷,對系統"點火".中斷中調用了do_timer函數。現在這是個很短的函數:
void do_timer(long cpl)
{
...
//根據優先順序調整進程運行時間
if(cpl)
current->utime++;
else
current->stime++;
//處理定時器中斷隊列
if(next_timer){
next_timer->jiffies--;
while(next_timer&&next_timer->jiffies<=0){
void(*fn)(void);
fn=next_timer->fn;
next_timer->fn=NULL;
next_timer=next_timer->next;
(fn)();
}
}
..
//對進程時間片減1。如果大於0 ,表示時間片還沒有用完,繼續
if((--current->counter>0)return;
//注意,內核態任務是不可搶占的,在0.11中,除非內核任務主動放棄處理器,它將一直運行。
if(!cpl)return;
//調度
schele();
}
4.進程的終止
進程可以自己中止,也可以被中止信號中止。do_exit執行退出。如果它有子進程的話,子進程就會成為孤兒進程,這里會將它的孩子託付給進程1(即init進程)管理。在成為僵死進程之後,還要通知父進程,因為他的父進程可能在等它呢。