Jump to content

[help] CPU consumption using FileReadToArray and ProcessClose


Go to solution Solved by Musashi,

Recommended Posts

Posted

Hello greetings. I have this problem with CPU consumption.

By having multiple .exe names in a test.ini file that FileReadToArray reads and closes with ProcessClose when opening the .exe

 

AN EXAMPLE;  

IF I HAVE MORE THAN 30 to 50 .EXE FILES WITH DIFFERENT NAMES IN TEST.INI THE CPU LOAD INCREASES.

 

SOME WAY TO AVOID CPU CONSUMPTION I WOULD APPRECIATE THE HELP. THIS IS MY CODE SO FAR.

#include <MsgBoxConstants.au3>
#include <GUIConstants.au3>


AdlibRegister("Example", 1000)


While 1


Wend

Func Example()
       
        Local $aArray = FileReadToArray(@ScriptDir & "\test.ini")
        Local $iLineCount = @extended
        If @error Then

        Else
                 Sleep(500)
                For $i = 0 To $iLineCount - 1 

                        If ProcessClose($aArray[$i]) Then 
                        EndIf
                Next
        EndIf
EndFunc   ;==>Example

 

Posted (edited)
2 hours ago, angel83 said:

SOME WAY TO AVOID CPU CONSUMPTION I WOULD APPRECIATE THE HELP. THIS IS MY CODE SO FAR.

I'm sorry, but this code makes no sense.

An .ini file typically has the following structure : 

[Sectionname1]

1..n Key=Value pairs

[Sectionname2]

1..n Key=Value pairs

and so on. If you read such a structure with FileReadToArray, you will not get valid file names.

Of course you can save a list of file names (.exe's) with the extension .ini, but that would be confusing. Please post your Test.ini.

AdlibRegister starts the Function Example every 1000 ms, the While Loop runs forever. So you get a huge number of ProcessClose attempts (from files that have not been started anywhere). Please describe what you actually want to achieve.

 

Edited by Musashi
Answer extended

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Posted (edited)

you need to change the logic, i.e.
you do the Array once at the beginning,
and then in each AdlibRegister cycle you simply check it

#include <File.au3>

Global $aArray = ReadTestFile()

AdlibRegister("_CheckIt", 1500)

While 1
    Sleep(50)
WEnd

Func ReadTestFile()
    Local $aArray, $sFile =  @ScriptDir & "\test.ini"
    _FileReadToArray($sFile, $aArray)
    If Not IsArray($aArray) Then Exit MsgBox(4096, @ScriptName, "There was an error reading the file." & @LF & $sFile)
    Return $aArray
EndFunc   ;==>ReadTestFile

Func _CheckIt()
    For $i = 1 To $aArray[0]
        ConsoleWrite($i & ") " & $aArray[$i])
        If ProcessExists($aArray[$i]) Then
            ConsoleWrite(" ProcessClose: " & ProcessClose($aArray[$i]) & @CRLF)
        EndIf
        ConsoleWrite("" & @CRLF)
    Next
EndFunc   ;==>_CheckIt

 

Edited by ioa747

I know that I know nothing

Posted

@ioa747 :

I suspect that the OP wants to work through a list of process names (that he has defined in a textfile) and, if they are currently running, close them.

This shall be done using AdlibRegister every 1000 ms, which is, in my opinion,  too short an interval, as ProcessClose (e.g. 50 x) takes some time. It would probably be best if the OP could specify his goal in more detail. 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Posted

apt observation
In this case, a safe way is to initialize it on every cycle.

#include <File.au3>

Global $aArray = ReadTestFile()

AdlibRegister("_CheckIt", 1500)

While 1
    Sleep(50)
WEnd

Func ReadTestFile()
    Local $aArray, $sFile =  @ScriptDir & "\test.ini"
    _FileReadToArray($sFile, $aArray)
    If Not IsArray($aArray) Then Exit MsgBox(4096, @ScriptName, "There was an error reading the file." & @LF & $sFile)
    Return $aArray
EndFunc   ;==>ReadTestFile

Func _CheckIt()
    AdlibUnRegister("_CheckIt")
    For $i = 1 To $aArray[0]
        ConsoleWrite($i & ") " & $aArray[$i])
        If ProcessExists($aArray[$i]) Then
            ConsoleWrite(" ProcessClose: " & ProcessClose($aArray[$i]) & @CRLF)
        EndIf
        ConsoleWrite("" & @CRLF)
    Next
    Sleep(500)
    AdlibRegister("_CheckIt", 1500)
EndFunc   ;==>_CheckIt

 

I know that I know nothing

Posted

It is a common belief that AdlibRegister will interrupt itself if the delay is too short for the function to complete.  But it will not. It will simply pass to the next cycle. Here a simple example of it.

HotKeySet("{ESC}", Terminate)
AdlibRegister(Test, 1000)

While Sleep(500)
WEnd

Func Test()
  For $i = 1 To 10
    Sleep(300)
  Next
  ConsoleWrite(@SEC & @CRLF)
EndFunc
Func Terminate()
  Exit
EndFunc

Even if the delay is 1 sec and the function takes 3 secs, it does not interrupt itself.  So there is not much need, IMO to unregister and reregister the function.

Posted

Musashi ] I understand that an ini file has the following structure found in your example. but I can also have a list of .exe executable names in an ini or txt. since FileReadToArray reads it.

.ini is just an example.  as I have it, with its structure.

.ini

example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe
example.exe

Posted

What I'm trying to do is not consume a lot of CPU trying to close all the processes.
I give you an example; When my .au3 script is running when I run ("notepad.exe") and it is in the .ini list, my .au3 script will kill the process ("notepad.exe")

 

but by having a large list in the .ini file of executables with different names the cpu increases a lot.

Posted
6 hours ago, angel83 said:

How can I make it work to read the executables from an ini or txt file?

If you want to use ProcessList, you may go this way :

#include <File.au3>

HotKeySet("{ESC}", Terminate) ; ESC to terminate the while-loop (and the script)

; Read your list (of .exe's) from a given textfile into an array :
Global $g_sSearchfile =  @ScriptDir & "\ProcessCloseList.txt"  ; textfile with processnames you want to close
Global $g_aSearchList, $g_aProcessList
_FileReadToArray($g_sSearchfile, $g_aSearchList)
If Not IsArray($g_aSearchList) Then Exit MsgBox(4096, @ScriptName, "There was an error reading the file." & @CRLF & $g_sSearchfile)

AdlibRegister(_CloseProcesses, 1000)

While Sleep(100)
WEnd

Func _CloseProcesses()
    For $i = 1 To $g_aSearchList[0]
        $g_aProcessList = ProcessList($g_aSearchList[$i])
        While $g_aProcessList[0][0] > 0
            ProcessClose($g_aProcessList[1][0])
            Sleep(100)
            $g_aProcessList = ProcessList($g_aSearchList[$i])
        WEnd
    Next
EndFunc

Func Terminate()
    Exit
EndFunc

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Posted

Thanks friend Musashi, your code works.
but I still have the same cpu consumption problem by having too many executables in the .txt file.
If I have a single executable.exe, it doesn't consume CPU at all. But if I have many examples more than 30, the CPU consumption increases. That is the problem I have that the more I have, the more CPU consumption. I would appreciate the help and I apologize for the inconvenience.

Posted
8 hours ago, angel83 said:

but I still have the same cpu consumption problem by having too many executables in the .txt file.

Hmm :think: !

Let's assume you have a list of 50 process names in your filelist.txt, such as :

Notepad.exe
Calc.exe
Processname03.exe
Processname04.exe
Processname05.exe
...
Processname50.exe

Let's further assume that all processes are currently running.

When you start the script, all these processes should be closed. This may increase the processor load for a short time.

The script now permanently checks whether one or more of the processes has been restarted and closes them.
(If you start Notepad.exe again, for example, the application will be closed almost immediately)

However, not all processes should normally be restarted every second by other applications. At least I have not noticed any particular increase in the processor load, as long as the script only checks for the existence of the processes.

So what could be the reason for the CPU consumption you observed? 

- You may be running one or more applications that continuously restart processes if they are not present.

- There are one or more processes that prove to be very persistent and can only be terminated using the Taskkill command.

But that is just a guess.

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

  • Solution
Posted

Addendum :

I have added a line to my script that writes the name, PID and @error result of each closed process to a log file. Maybe this brings us a little closer to the problem :).

#include <File.au3>

HotKeySet("{ESC}", Terminate) ; ESC to terminate the while-loop (and the script)

; Read your list (of .exe's) from a given textfile into an array :
Global $g_sSearchfile =  @ScriptDir & "\ProcessCloseList.txt"  ; textfile with processnames you want to close
Global $g_aSearchList, $g_aProcessList
_FileReadToArray($g_sSearchfile, $g_aSearchList)
If Not IsArray($g_aSearchList) Then Exit MsgBox(4096, @ScriptName, "There was an error reading the file." & @CRLF & $g_sSearchfile)

AdlibRegister(_CloseProcesses, 1000)

While Sleep(100)
WEnd

Func _CloseProcesses()
    For $i = 1 To $g_aSearchList[0]
        $g_aProcessList = ProcessList($g_aSearchList[$i])
        While $g_aProcessList[0][0] > 0
            ProcessClose($g_aProcessList[1][0])

            ; *** for testing purposes only : Write the result of ProcessClose to a log file
            _FileWriteLog(@ScriptDir & "\CloseProcesses.log", "Error=" & @error & "   PID=" & $g_aProcessList[1][1] &  "   Processname=" & $g_aProcessList[1][0])

            Sleep(100)
            $g_aProcessList = ProcessList($g_aSearchList[$i])
        WEnd
    Next
EndFunc

Func Terminate()
    Exit
EndFunc

 

Musashi-C64.png

"In the beginning the Universe was created. This has made a lot of people very angry and been widely regarded as a bad move."

Posted

thanks to a that continues with CPU consumption. but your code consumes less, thank you very much friend Musashi.

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...