1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101
| #include "_public.h"
CLogFile logfile;
int main(int argc,char *argv[]) { if (argc != 2) { printf("\n"); printf("Using:./checkproc logfilename\n");
printf("Example:/project/tools1/bin/procctl 10 /project/tools1/bin/checkproc /tmp/log/checkproc.log\n\n");
printf("本程序用于检查后台服务程序是否超时,如果已超时,就终止它。\n"); printf("注意:\n"); printf(" 1)本程序由procctl启动,运行周期建议为10秒。\n"); printf(" 2)为了避免被普通用户误杀,本程序应该用root用户启动。\n"); printf(" 3)如果要停止本程序,只能用killall -9 终止。\n\n\n");
return 0; }
CloseIOAndSignal(true);
if (logfile.Open(argv[1],"a+")==false) { printf("logfile.Open(%s) failed.\n",argv[1]); return -1; }
int shmid=0;
if ( (shmid = shmget((key_t)SHMKEYP, MAXNUMP*sizeof(struct st_procinfo), 0666|IPC_CREAT)) == -1) { logfile.Write("创建/获取共享内存(%x)失败。\n",SHMKEYP); return false; }
struct st_procinfo *shm=(struct st_procinfo *)shmat(shmid, 0, 0);
for (int ii=0;ii<MAXNUMP;ii++) { if (shm[ii].pid==0) continue;
int iret=kill(shm[ii].pid,0); if (iret==-1) { logfile.Write("进程pid=%d(%s)已经不存在。\n",(shm+ii)->pid,(shm+ii)->pname); memset(shm+ii,0,sizeof(struct st_procinfo)); continue; }
time_t now=time(0);
if (now-shm[ii].atime<shm[ii].timeout) continue;
logfile.Write("进程pid=%d(%s)已经超时。\n",(shm+ii)->pid,(shm+ii)->pname);
kill(shm[ii].pid,15);
for (int jj=0;jj<5;jj++) { sleep(1); iret=kill(shm[ii].pid,0); if (iret==-1) break; }
if (iret==-1) logfile.Write("进程pid=%d(%s)已经正常终止。\n",(shm+ii)->pid,(shm+ii)->pname); else { kill(shm[ii].pid,9); logfile.Write("进程pid=%d(%s)已经强制终止。\n",(shm+ii)->pid,(shm+ii)->pname); } memset(shm+ii,0,sizeof(struct st_procinfo)); }
shmdt(shm);
return 0; }
|