void mypsFrame::OnTimer1Trigger1(wxTimerEvent& event)
{
cpus = cpus_read(cpus);
wxString text = wxString::Format(_T("CPU Usage(Total) : %.2f%%\nCPU Usage(User) : %.2f%%\nCPU Usage(Kernel) : %.2f%%\n"),
cpus->usage_tot,
cpus->usage_usr,
cpus->usage_krn);
StaticText1->SetLabel(text);
mems = mems_read(mems);
text = wxString::Format(_T("MemTotal : %d KB\nMemUsed : %d KB\nMemFree : %d KB\n\nSwapTotal : %d KB\nSwapUsed : %d KB\nSwapFree : %d KB\n\nBuffers : %d KB\nCached : %dKB"),
mems->memtotal,
mems->memtotal - mems->memfree,
mems->memfree,
mems->swaptotal,
mems->swaptotal - mems->swapfree,
mems->swapfree,
mems->buffers,
mems->cached);
StaticText2->SetLabel(text);
int sinceboot = 0;
int running = 0;
int tickspersec = 0;
int sec = 0;
int diff[2];
float scale = 0.0;
double itemIndex = 0.0;
int numproc = 0;
int idx = 0;
procVectItor itor;
PROC_t tempps;
struct dirent *item;
DIR *dp = NULL;
if (dp = opendir("/proc/"))
{
while (1)
{
item = readdir(dp);
if (item == NULL)
break;
if (atoi(item->d_name))
{
// read on pid stat
++numproc;
// PID COMMAND USER %CPU %MEM %TIME
procs = procstat(item->d_name, procs);
procs->flag = 1;
if (ps.empty()) {
ps.push_back(*procs);
} else if ((itor = (find(ps.begin(), ps.end(), procs->pid))) != ps.end()) {
procs->utime_sav = itor->utime_sav;
procs->stimev_sav = itor->stimev_sav;
ps.erase(itor);
ps.insert(itor, *procs);
} else {
ps.push_back(*procs);
}
}
}
closedir(dp);
sort(ps.begin(), ps.end());
}
if (ListCtrl1->GetItemCount() == 0)
{
for (itor = ps.begin(); itor != ps.end(); ++itor)
{
sinceboot = gettimesinceboot();
running = sinceboot - itor->start_time;
tickspersec = sysconf(_SC_CLK_TCK);
sec = (int)running / tickspersec;
diff[0] = itor->utime - itor->utime_sav;
diff[1] = itor->stimev - itor->stimev_sav;
scale = (diff[0] + diff[1]) * 100 / (float)cpus->total_sav;
itor->utime_sav = itor->utime;
itor->stimev_sav = itor->stimev;
itor->cpu_usage = scale;
itor->flag = 0;
text = wxString::Format(_T("%d"), (int)itor->pid);
itemIndex = ListCtrl1->InsertItem(idPID, text);
text = wxString::FromAscii(itor->tcomm);
ListCtrl1->SetItem(itemIndex, idCMD, text);
text = wxString::FromAscii(itor->username);
ListCtrl1->SetItem(itemIndex, idUSR, text);
text = wxString::Format(_T("%.1f"), scale);
ListCtrl1->SetItem(itemIndex, idCPU, text);
text = wxString::Format(_T("%dKB"), (int)itor->rss);
ListCtrl1->SetItem(itemIndex, idMEM, text);
text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60);
ListCtrl1->SetItem(itemIndex, idTME, text);
}
} else {
for (itor = ps.begin(); itor != ps.end(); ++itor)
{
text = wxString::Format(_T("%d"), (int)itor->pid);
itemIndex = ListCtrl1->FindItem(idPID, text);
if(itor->flag == 0)
{
ListCtrl1->DeleteItem(itemIndex);
continue;
}
sinceboot = gettimesinceboot();
running = sinceboot - itor->start_time;
tickspersec = sysconf(_SC_CLK_TCK);
sec = (int)running / tickspersec;
diff[0] = itor->utime - itor->utime_sav;
diff[1] = itor->stimev - itor->stimev_sav;
scale = (diff[0] + diff[1]) * 100 / (float)cpus->total_sav;
itor->utime_sav = itor->utime;
itor->stimev_sav = itor->stimev;
itor->cpu_usage = scale;
itor->flag = 0;
if(itemIndex < 0)
{
text = wxString::Format(_T("%d"), (int)itor->pid);
itemIndex = ListCtrl1->InsertItem(idPID, text);
text = wxString::FromAscii(itor->tcomm);
ListCtrl1->SetItem(itemIndex, idCMD, text);
text = wxString::FromAscii(itor->username);
ListCtrl1->SetItem(itemIndex, idUSR, text);
text = wxString::Format(_T("%.1f"), scale);
ListCtrl1->SetItem(itemIndex, idCPU, text);
text = wxString::Format(_T("%dKB"), (int)itor->rss);
ListCtrl1->SetItem(itemIndex, idMEM, text);
text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60);
ListCtrl1->SetItem(itemIndex, idTME, text);
continue;
}
text = wxString::Format(_T("%d"), (int)itor->pid);
ListCtrl1->SetItem(itemIndex, idPID, text);
text = wxString::FromAscii(itor->tcomm);
ListCtrl1->SetItem(itemIndex, idCMD, text);
text = wxString::FromAscii(itor->username);
ListCtrl1->SetItem(itemIndex, idUSR, text);
text = wxString::Format(_T("%.1f"), scale);
ListCtrl1->SetItem(itemIndex, idCPU, text);
text = wxString::Format(_T("%dKB"), (int)itor->rss);
ListCtrl1->SetItem(itemIndex, idMEM, text);
text = wxString::Format(_T("%2dh:%dm"), (int)((int)(sec / 60) / 60), (int)((sec / 60))%60);
ListCtrl1->SetItem(itemIndex, idTME, text);
}
}
//Note: 이 부분에 리스트 컨트롤 정렬을 넣고 싶으나 레퍼런스가 부족하다.
// ::SetColumnsOrder() 함수를 제공하나 윈도우만 가능하다.
text = wxString::Format(_T("프로세스: %d\t CPU 사용: %3d%%\t실제 메모리: %3d%%"), numproc, (int)cpus->usage_tot, ((mems->memtotal - mems->memfree) * 100)/mems->memtotal);
StatusBar1->PushStatusText(text);
}
void mypsFrame::OnListCtrl1ItemRClick(wxListEvent& event)
{
wxMessageDialog *Dlg = new wxMessageDialog(NULL, _T("이 프로세스를 끝내시겠습니까?\n\n비정상적인 종료는 시스템이 불안정해질 수 있습니다. 계속하시겠습니까?"), _T("kill"), wxOK | wxCANCEL | wxICON_QUESTION);
if(Dlg->ShowModal() == wxID_CANCEL)
return;
wxString text = event.GetText();
int pid = atoi((const char*)text.mb_str(wxConvUTF8));
kill(pid, SIGTERM);
}