⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 top.c

📁 Linux下进程监控相关源代码
💻 C
📖 第 1 页 / 共 4 页
字号:
	time/=60;	/* minutes */	sprintf(buf,"%dm",time);	if (strlen(buf)<=width) 		return buf;	time/=60;	/* hours */	sprintf(buf,"%dh",time);	if (strlen(buf)<=width) 		return buf;	time/=24;	/* days */	sprintf(buf,"%dd",time);	if (strlen(buf)<=width) 		return buf;		time/=7;	/* weeks */	sprintf(buf,"%dw",time);	return buf;	/* this is our last try; 				if it still doesn't fit, too bad. */	/* :-) I suppose if someone has a SMP version of Linux with a few           thousand processors, they could accumulate 18 years of CPU time... */           }/*   scale_k(k,width,unit)  - interprets k as a count, formats to fit width.                            if unit is 0, k is a byte count; 1 is a kilobyte			    count; 2 for megabytes; 3 for gigabytes.*/char *scale_k(int k,int width,int unit) {		/* kilobytes, megabytes, gigabytes, too-big-for-int-bytes */	static double scale[]={1024,1024*1024,1024*1024*1024,0};		/* kilo, mega, giga, tera */	static char unitletters[]={'K','M','G','T',0};	static char buf[100];	char *up;	double *dp;	/* Try successively higher units until it fits */	sprintf(buf,"%d",k);	if (strlen(buf)<=width) 		return buf;	for (up=unitletters+unit,dp=scale ; *dp ; ++dp,++up) {		sprintf(buf,"%.1f%c",k / *dp,*up);		if (strlen(buf)<=width) 			return buf;		sprintf(buf,"%d%c",(int)(k / *dp),*up);		if (strlen(buf)<=width) 			return buf;	}	/* Give up; give them what we got on our shortest attempt */	return buf;}/* *####################################################################### *####  Routines handling the main top screen:                   ######## *####    show_task_info, show_procs, show_memory, do_stats      ######## *####################################################################### */	/*	 * Displays infos for a single task	 */void show_task_info(proc_t *task, int pmem){    int i,j;    unsigned int t;    char *cmdptr;    char tmp[2048], tmp2[2048] = "", tmp3[2048] = "", *p;    for (i = 0; i < Numfields; i++) {	tmp[0] = 0;	switch (pflags[i]) {	  case P_PID:	    sprintf(tmp, "%5d ", task->pid);	    break;	  case P_PPID:	    sprintf(tmp, "%5d ", task->ppid);	    break;	  case P_EUID:	    sprintf(tmp, "%4d ", task->euid);	    break;	  case P_EUSER:	    sprintf(tmp, "%-8.8s ", task->euser);	    break;	  case P_PCPU:	    sprintf(tmp, "%4.1f ", (float)task->pcpu / 10);	    break;	  case P_LCPU:	    sprintf(tmp, "%2d ", task->lproc);	    break;	  case P_PMEM:	    sprintf(tmp, "%4.1f ", (float)pmem / 10);	    break;	  case P_TTY: {	      char outbuf[9];	      dev_to_tty(outbuf, 8, task->tty, task->pid, ABBREV_DEV);	      sprintf(tmp, "%-8.8s ", outbuf);	    }	    break;	  case P_PRI:	    sprintf(tmp, "%3.3s ", scale_k(task->priority, 3, 0));	    break;	  case P_NICE:	    sprintf(tmp, "%3.3s ", scale_k(task->nice, 3, 0));	    break;	  case P_PAGEIN:	    sprintf(tmp, "%6.6s ", scale_k(task->maj_flt, 6, 0));	    break;	  case P_TSIZ:	    sprintf(tmp, "%5.5s ",		scale_k(((task->end_code - task->start_code) / 1024), 5, 1));	    break;	  case P_DSIZ:	    sprintf(tmp, "%5.5s ",		scale_k(((task->vsize - task->end_code) / 1024), 5, 1));	    break;	  case P_SIZE:	    sprintf(tmp, "%5.5s ", scale_k((task->size << CL_pg_shift), 5, 1));	    break;	  case P_TRS:	    sprintf(tmp, "%4.4s ", scale_k((task->trs << CL_pg_shift), 4, 1));	    break;	  case P_SWAP:	    sprintf(tmp, "%4.4s ",		scale_k(((task->size - task->resident) << CL_pg_shift), 4, 1));	    break;	  case P_SHARE:	    sprintf(tmp, "%5.5s ", scale_k((task->share << CL_pg_shift), 5, 1));	    break;	  case P_A:	    sprintf(tmp, "%3.3s ", "NYI");	    break;	  case P_WP:	    sprintf(tmp, "%3.3s ", "NYI");	    break;	  case P_DT:	    sprintf(tmp, "%3.3s ", scale_k(task->dt, 3, 0));	    break;	  case P_RSS:	/* resident not rss, it seems to be more correct. */	    sprintf(tmp, "%4.4s ",		scale_k((task->resident << CL_pg_shift), 4, 1));	    break;	  case P_WCHAN:	    if (!CL_wchan_nout)		sprintf(tmp, "%-9.9s ", wchan(task->wchan));	    else		sprintf(tmp, "%-9lx", task->wchan);	    break;	  case P_STAT:	    sprintf(tmp, "%-4.4s ", status(task));	    break;	  case P_TIME:	    t = (task->utime + task->stime) / Hertz;	    if (Cumulative)		t += (task->cutime + task->cstime) / Hertz;	    sprintf(tmp, "%6.6s ", scale_time(t,6));	    break;	  case P_COMMAND:	    if (!show_cmd && task->cmdline && *(task->cmdline)) {	        j=0;	        while(((task->cmdline)[j] != NULL) && (strlen(tmp3)<1020)){/* #if 0 */ /* This is useless? FIXME */		    if (j > 0)			strcat(tmp3, " ");/* #endif */		    strncat(tmp3, (task->cmdline)[j], 1000);		    j++; 	        }	        cmdptr = tmp3;	    } else {		cmdptr = task->cmd;	    }	    if (strlen(cmdptr) > Maxcmd)		cmdptr[Maxcmd - 1] = 0;	    sprintf(tmp, "%s", cmdptr);	    tmp3[0]=0;	    break;	  case P_FLAGS:	    sprintf(tmp, "%8lx ", task->flags);	    break;	}	strcat(tmp2, tmp);    }    if (strlen(tmp2) > Cols - 1)	tmp2[Cols - 1] = 0;    /* take care of cases like:       perl -e 'foo          bar foo bar          foo          # end of perl script'    */    for (p=tmp2;*p;++p)        if (!isgraph(*p))            *p=' ';    printf("\n%s", tmp2);    PUTP(top_clrtoeol);}/* * This is the real program!  Read process info and display it. * One could differentiate options of readproctable2, perhaps it * would be useful to support the PROC_UID and PROC_TTY * as command line options. */void show_procs(void){    static proc_t **p_table=NULL;    static int proc_flags;    int count;    int ActualLines;    float elapsed_time;    unsigned int main_mem;    static int first=0;    if (first==0) {	proc_flags=PROC_FILLMEM|PROC_FILLCMD|PROC_FILLUSR;	if (monpids_index)	    proc_flags |= PROC_PID;	p_table=readproctab2(proc_flags, p_table, monpids);	elapsed_time = get_elapsed_time();	do_stats(p_table, elapsed_time, 0);	sleep(1);	first=1;    }    if (first && Batch)	    fputs("\n\n",stdout);    /* Display the load averages. */    PUTP(ho);    PUTP(md);    if (show_loadav) {	printf("%s", sprint_uptime());	PUTP(top_clrtoeol);	putchar('\n');    }    p_table=readproctab2(proc_flags, p_table, monpids);    /* Immediately find out the elapsed time for the frame. */    elapsed_time = get_elapsed_time();    /* Display the system stats, calculate percent CPU time     * and sort the list. */    do_stats(p_table, elapsed_time,1);    /* Display the memory and swap space usage. */    main_mem = show_meminfo();    if (strlen(Header) + 2 > Cols)	Header[Cols - 2] = 0;    PUTP(mr);    fputs(Header, stdout);    PUTP(top_clrtoeol);    PUTP(me);    /*     * Finally!  Loop through to find the top task, and display it.     * Lather, rinse, repeat.     */    count = 0;    ActualLines = 0;    while ((ActualLines < Maxlines) && (p_table[count]->pid!=-1)) {	int pmem;	char stat;	stat = p_table[count]->state;	if ( (!Noidle || (stat != 'S' && stat != 'Z')) &&	     ( (CurrUser[0] == '\0') ||	      (!strcmp((char *)CurrUser,p_table[count]->euser) ) ) ) {	    /*	     * Show task info.	     */	    pmem = p_table[count]->resident * 1000 / (main_mem / 4);	    show_task_info(p_table[count], pmem);	    if (!Batch)	    	ActualLines++;	}	count++;    }    PUTP(top_clrtobot);    PUTP(tgoto(cm, 0, header_lines - 2));    fflush(stdout);}/* * Finds the current time (in microseconds) and calculates the time * elapsed since the last update. This is essential for computing * percent CPU usage. */float get_elapsed_time(void){    struct timeval time;    static struct timeval oldtime;    struct timezone timez;    float elapsed_time;    gettimeofday(&time, &timez);    elapsed_time = (time.tv_sec - oldtime.tv_sec)	+ (float) (time.tv_usec - oldtime.tv_usec) / 1000000.0;    oldtime.tv_sec = time.tv_sec;    oldtime.tv_usec = time.tv_usec;    return (elapsed_time);}/* * Reads the memory info and displays it.  Returns the total memory * available, for use in percent memory usage calculations. */unsigned show_meminfo(void){    unsigned long long **mem;    if (!(mem = meminfo()) ||	/* read+parse /proc/meminfo */	mem[meminfo_main][meminfo_total] == 0) {	/* cannot normalize mem usage */	fprintf(stderr, "Cannot get size of memory from /proc/meminfo\n");	error_end(1);    }    if (show_memory) {	printf("Mem:  %7LdK av, %7LdK used, %7LdK free, %7LdK shrd, %7LdK buff",	       mem[meminfo_main][meminfo_total] >> 10,	       mem[meminfo_main][meminfo_used] >> 10,	       mem[meminfo_main][meminfo_free] >> 10,	       mem[meminfo_main][meminfo_shared] >> 10,	       mem[meminfo_main][meminfo_buffers] >> 10);	PUTP(top_clrtoeol);	putchar('\n');	printf("Swap: %7LdK av, %7LdK used, %7LdK free                 %7LdK cached",	       mem[meminfo_swap][meminfo_total] >> 10,	       mem[meminfo_swap][meminfo_used] >> 10,	       mem[meminfo_swap][meminfo_free] >> 10,	       mem[meminfo_total][meminfo_cached] >> 10);	PUTP(top_clrtoeol);	putchar('\n');    }    PUTP(me);    PUTP(top_clrtoeol);    putchar('\n');    return mem[meminfo_main][meminfo_total] >> 10;}/* * Calculates the number of tasks in each state (running, sleeping, etc.). * Calculates the CPU time in each state (system, user, nice, etc). * Calculates percent cpu usage for each task. */void do_stats(proc_t** p, float elapsed_time, int pass){    proc_t *this;    int index, total_time, cpumap, i, n = 0;    int sleeping = 0, stopped = 0, zombie = 0, running = 0;    unsigned long system_ticks = 0, user_ticks = 0, nice_ticks = 0, idle_ticks;    static int prev_count = 0;    int stime, utime;    /* start with one 4K page as a reasonable allocate size */    static int save_history_size = sizeof(struct save_hist) * 204;    static struct save_hist *save_history;    struct save_hist *New_save_hist;    static int *s_ticks_o = NULL, *u_ticks_o = NULL,               *n_ticks_o = NULL, *i_ticks_o = NULL;    int s_ticks, u_ticks, n_ticks, i_ticks, t_ticks;    char str[128];    FILE *file;    if (!save_history)	save_history = xcalloc(NULL, save_history_size);    New_save_hist = xcalloc(NULL, save_history_size);    if(s_ticks_o == NULL) {      s_ticks_o = (int *)malloc(nr_cpu * sizeof(int));      u_ticks_o = (int *)malloc(nr_cpu * sizeof(int));      n_ticks_o = (int *)malloc(nr_cpu * sizeof(int));      i_ticks_o = (int *)malloc(nr_cpu * sizeof(int));    }    idle_ticks = 1000 * nr_cpu;    /*     * Make a pass through the data to get stats.     */    index = 0;    while (p[n]->pid != -1) {	this = p[n];	switch (this->state) {	  case 'S':	  case 'D':	    sleeping++;	    break;	  case 'T':	    stopped++;	    break;	  case 'Z':	    zombie++;	    break;	  case 'R':	    running++;	    break;	  default:	    /* Don't know how to handle this one. */	    break;        }	/*	 * Calculate time in this process.  Time is sum of user time	 * (utime) plus system time (stime).	 */	total_time = this->utime + this->stime;	if (index * sizeof(struct save_hist) >= save_history_size) {	    save_history_size *= 2;	    save_history = xrealloc(save_history, save_history_size);	    New_save_hist = xrealloc(New_save_hist, save_history_size);	}	New_save_hist[index].ticks = total_time;	New_save_hist[index].pid = this->pid;	stime = this->stime;	utime = this->utime;	New_save_hist[index].stime = stime;	New_save_hist[index].utime = utime;	/* find matching entry from previous pass */	for (i = 0; i < prev_count; i++) {	    if (save_history[i].pid == this->pid) {		total_time -= save_history[i].ticks;		stime -= save_history[i].stime;		utime -= save_history[i].utime;		i = prev_count;	    }	}	/*	 * Calculate percent cpu time for this task.	 */	this->pcpu = (total_time * 10 * 100/Hertz) / elapsed_time;	if (this->pcpu > 999)	    this->pcpu = 999;	/*	 * Calculate time in idle, system, user and niced tasks.	 */	idle_ticks -= this->pcpu;	system_ticks += stime;	user_ticks += utime;	if (this->nice > 0)	    nice_ticks += this->pcpu;	/*	 * If in Sun-mode, adjust cpu percentage not only for	 * the cpu the process is running on, but for all cpu together.	 */	if(!Irixmode) {	  this->pcpu /= nr_cpu;	  }		index++;	n++;    }    if (idle_ticks < 0)

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -