powered by simpleCommunicator - 2.0.53     © 2025 Programmizd 02
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как получить загрузку CPU в % программно?
4 сообщений из 4, страница 1 из 1
Как получить загрузку CPU в % программно?
    #38412392
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обнаружил что прога (телефония) при большой нагрузке (много параллельных процессов) может скрашить.
Устойчивость достаточно хорошая но все же.
Конкретные причины искать тяжело (если не сказать малореально), хотя ищу по возможности.
Как-то это зависит от нагрузки на процессор.
Хочу придать больше устойчивости.
В библиотеке есть таймеры
Обычно
thread->WaitForTermination(10000) 'если 10 сек нет ответа -> генерировать краш
По совету одного человека сделал
thread->WaitForTermination(100000) 'до 100сек
но это мало помогает, либо если бобик сдох, то все равно сдох,
либо причина в другом.

Что я хочу попытаться сделать (хотя б для теста).
Пассивные процессы (статистика и т.п.) -здесь я бессилен.
Активные процессы - могу сделать отсрочку на запуск нового процесса.
Хочу попробовать вычислить CPU Usage и если превосходит планку то от запуска временно воздержаться.
То что в диспетчере задач.

Реально? Как?
...
Рейтинг: 0 / 0
Как получить загрузку CPU в % программно?
    #38412464
Фотография lbppb
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Дмитрий77,

Пример для Excel, а дальше адаптируйте под себя. Вот здесь можно узнать больше.

Код: vbnet
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.
Sub WMIService()

'http://msdn.microsoft.com/en-us/library/aa394599(v=vs.85).aspx

Dim strComputer As String
Dim x As Integer
Dim myRow As Integer
Dim objWMIService As Object
Dim colProcesses As Object
Dim objItem As Object

strComputer = "."
Cells(1, 1).Value = "Process Name"
Cells(1, 2).Value = "CPU Usage"
 
 
Do Until x > 1
    myRow = 1
     
    Set objWMIService = GetObject("winmgmts:\\" & strComputer & "\root\cimv2")
    Set colProcesses = objWMIService.ExecQuery("Select * from Win32_PerfFormattedData_PerfProc_Process", , 48)
     
    For Each objItem In colProcesses
        If objItem.Name <> "Idle" And objItem.Name <> "_Total" Then
            myRow = myRow + 1
            Cells(myRow, 1).Value = objItem.Name
            Cells(myRow, 2).Value = objItem.PercentProcessorTime
        End If
    Next
     
    DoEvents
Loop
    
End Sub
...
Рейтинг: 0 / 0
Как получить загрузку CPU в % программно?
    #38412483
Дмитрий77
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
lbppb,

WMI на мой взгляд не надежно (по опыту с модемами и портами) - и без его знает сколько оно само ресурсов расходует.

Я вот так сделал:

Код: vbnet
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.
Private Sub Timer1_Timer()
  Dim totalCpuUsage As Long
  totalCpuUsage = total_CPU_Usage(eIdle, eKernel, eUser)
  Me.Label1.Caption = CStr(totalCpuUsage) & " %"
  Me.LabelLarge.Caption = IIf(totalCpuUsage > 20, "МНОГО", "")
  
  If total_CPU_Usage(eIdle, eKernel, eUser) > 20 Then Exit Sub  'Timer1.Interval = 300
  '===========КОД ЗАПУСКА НОВОГО ПРОЦЕССА (усиливает нагрузку)======================
End Sub

'------------------------------------------

Option Explicit

Private Declare Function GetSystemTimes Lib "kernel32.dll" (ByRef idleTime As _
 Currency, ByRef kernelTime As Currency, ByRef userTime As Currency) As Boolean

'These variable are to hold the ending (current) times values.
Public eIdle As Currency
Public eKernel As Currency
Public eUser As Currency

Public Function total_CPU_Usage _
 (ByRef eIdle As Currency, ByRef eKernel As Currency, ByRef eUser As Currency) As Long
  'Will contain the calculated cpu usage as a percent value.
  
  'These are to hold the starting times values.
  Dim sIdle As Currency
  Dim sKernel As Currency
  Dim sUser As Currency
  
  'These will hold the values that are calculated from the ending and starting times.
  Dim cIdle As Currency
  Dim cKernel As Currency
  Dim cUser As Currency
  
  'This variable will contain the values of cKernel + cUser.
  Dim systemTime As Long
  
  'Starting Times values
  sIdle = eIdle
  sKernel = eKernel
  sUser = eUser
  
  'Retrieve the current Times values
  GetSystemTimes eIdle, eKernel, eUser
  eIdle = Val(eIdle)
  eKernel = Val(eKernel)
  eUser = Val(eUser)
  
  'Get the values calculated between the starting and ending Times values.
  cIdle = (eIdle - sIdle)
  cKernel = (eKernel - sKernel)
  cUser = (eUser - sUser)
  
  'Calculate the total system time. Which is Kernel and User time together.
  systemTime = (cKernel + cUser)
  
  'Now calculate the values as a percentage based number.
  If systemTime <> 0 Then total_CPU_Usage = CLng((systemTime - cIdle) * (100) / (systemTime))
End Function



Ну, в моем случае ограничение 20% вроде как помогает, ограничивая излишнюю активность и перераспределяя ее во времени.
Таймер 300мс -если зашкалит, то "новое действо" отменяется до след. таймера,
само "действо" создает максимальную нагрузку естественно в первый момент (запуск процесса, запрос-запись в БД и т.п.),
поэтому отказоустойчивости это дело способствует.

Вопрос только в том какую величину вычислять для сравнения с критерием и сколько % брать за критерий.

Сами процессы (тел. звонки) много не просят,
основная энергия идет на установление соединения и запись всяких логов с пиком в начале и конце вызова.
На конец я влиять не могу, а вот на начало очень даже.

Т.е. напр. 50 одновременных вызовов (разрешенный тест максимум кот. проходит по логике теста по времени бы прошел - по 25 сек каждый вызов, и инициализация не чаще чем (+/-300мс (таймер VB)) +( +/-500 мс(таймер C++)) на моем компе не тянут. Ограничение 30% CPU сбрасывает в район 40 вызовов, при этом таки есть вероятность (но уже малая) краша.
Ограничение же в 20% CPU сбрасывает в район 35 вызовов но при этом краш уже считай исключен.

Причем планку 20% скорее всего можно поднять, а сбои происходят из-за случайных скачков (50%-10%-80%) - я беру CPU по соседним точкам 300мс, и в 10% я напр. "бабахнул". М.б. имеет смысл интерполировать-усреднять по скажем 10 предыдущим значениям(или даже по большему количеству -понятно что такие нагрузки на игровом компе не запускают и интерполяция скажем по 100-200 точкам (30-60сек) уже покажет среднюю нагрузку, кот. например превышать не надо)? Но сильных вычислений каждый раз тоже ясно дело не хотелось бы. Есть идеи?

Я на всякий случай тест-проект приложил.
Да и как быть с двух- трех- процессорностью? У меня 2 процессора, но без "контроля" может приближаться к 100%.
...
Рейтинг: 0 / 0
Как получить загрузку CPU в % программно?
    #38433620
Фотография Андрей159
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
В Bass.dll есть функция такая. Это библиотека связанна с музыкой, с mp3.... Если других вариантов не найдешь, попробуй. Постоянно пользуюсь.
...
Рейтинг: 0 / 0
4 сообщений из 4, страница 1 из 1
Форумы / Visual Basic [игнор отключен] [закрыт для гостей] / Как получить загрузку CPU в % программно?
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]