进程监控源码
Ⅰ 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进程)管理。在成为僵死进程之后,还要通知父进程,因为他的父进程可能在等它呢。