Procese
La lansarea unei aplicații, sistemul de operare creează pentru aceasta un proces separat, căruia i se alocă un spațiu de adresă specific în memorie și care este izolat de alte procese. Un proces poate avea mai multe fire de execuție (threads). În mod minim, un proces conține un fir de execuție principal.
Într-o aplicație C#, punctul de intrare al programului este metoda Main. Apelul acestei metode creează automat firul de execuție principal, iar din acest fir pot fi lansate fire de execuție secundare.
În .NET, un proces este reprezentat de clasa Process din spațiul de nume System.Diagnostics. Această clasă permite gestionarea proceselor deja lansate, precum și lansarea unor procese noi. În această clasă sunt definite mai multe proprietăți și metode care permit obținerea informațiilor despre procese și gestionarea lor:
- Handle: returnează descriptorul procesului
- Id: obține identificatorul unic al procesului în cadrul sesiunii curente a sistemului de operare
- MachineName: returnează numele calculatorului pe care este lansat procesul
- MainModule: reprezintă modulul principal – fișierul executabil al programului, reprezentat de un obiect de tip ProcessModule
- Modules: obține accesul la colecția ProcessModuleCollection, care stochează, sub formă de obiecte ProcessModule, setul de module (de exemplu, fișiere dll și exe) încărcate în cadrul procesului respectiv
- ProcessName: returnează numele procesului, care adesea coincide cu numele aplicației
- StartTime: returnează ora la care a fost lansat procesul
- PageMemorySize64: returnează volumul de memorie alocat pentru acest proces
- VirtualMemorySize64: returnează volumul de memorie virtuală alocat pentru acest proces
Metode importante:
- CloseMainWindow(): închide fereastra procesului care are interfață grafică
- GetProcesses(): returnează un array cu toate procesele lansate
- GetProcessesByName(): returnează procesele după numele lor (pot fi lansate mai multe instanțe ale aceleași aplicații, deci returnează un array)
- GetProcessById(): returnează procesul după Id (pot fi lansate mai multe instanțe ale aceleași aplicații, deci returnează un array)
- Kill(): oprește procesul
- Start(): lansează un proces nou
De exemplu, să analizăm procesul curent:
using System.Diagnostics;
var process = Process.GetCurrentProcess();
Console.WriteLine($"Id: {process.Id}");
Console.WriteLine($"Name: {process.ProcessName}");
Console.WriteLine($"VirtualMemory: {process.VirtualMemorySize64}");
Pentru a obține toate procesele lansate:
using System.Diagnostics;
foreach(Process process in Process.GetProcesses())
{
// afișăm id și numele procesului
Console.WriteLine($"ID: {process.Id} Name: {process.ProcessName}");
}
Pentru a obține ID-urile proceselor care reprezintă instanțele lansate ale Visual Studio:
using System.Diagnostics;
Process[] vsProcs = Process.GetProcessesByName("devenv"); // pentru Windows
// Process[] vsProcs = Process.GetProcessesByName("VisualStudio"); // pentru MacOS
foreach (var proc in vsProcs)
Console.WriteLine($"ID: {proc.Id}");
Firele de execuție ale procesului
Proprietatea Threads reprezintă colecția firelor de execuție ale procesului - un obiect ProcessThreadCollection, fiecare fir de execuție fiind un obiect ProcessThread. În această clasă, se remarcă următoarele proprietăți:
- CurrentPriority: returnează prioritatea curentă a firului de execuție
- Id: identificatorul firului de execuție
- IdealProcessor: permite setarea procesorului pentru executarea firului de execuție
- PriorityLevel: nivelul de prioritate al firului de execuție
- StartAddress: adresa în memorie a funcției care a lansat firul de execuție
- StartTime: ora lansării firului de execuție (suportată doar pe Windows și Linux)
De exemplu, să obținem toate firele de execuție ale procesului Visual Studio:
using System.Diagnostics;
Process proc = Process.GetProcessesByName("devenv")[0]; // Windows
// Process proc = Process.GetProcessesByName("VisualStudio")[0]; // MacOS
ProcessThreadCollection processThreads = proc.Threads;
foreach(ProcessThread thread in processThreads)
{
Console.WriteLine($"ThreadId: {thread.Id}");
}
Modulele procesului
O aplicație poate folosi un set de biblioteci și module terțe. Pentru a le obține, clasa Process are proprietatea Modules, care reprezintă un obiect ProcessModuleCollection. Fiecare modul este reprezentat de clasa ProcessModule, care include următoarele proprietăți:
- BaseAddress: adresa modulului în memorie
- FileName: calea completă către fișierul modulului
- EntryPointAddress: adresa funcției în memorie care a lansat modulul
- ModuleName: numele modulului (numele scurt al fișierului)
- ModuleMemorySize: returnează volumul de memorie necesar pentru încărcarea modulului
Pentru a obține toate modulele folosite de Visual Studio:
using System.Diagnostics;
Process proc = Process.GetProcessesByName("devenv")[0]; // pentru Windows
// Process proc = Process.GetProcessesByName("VisualStudio")[0]; // pentru MacOS
ProcessModuleCollection modules = proc.Modules;
foreach(ProcessModule module in modules)
{
Console.WriteLine($"Name: {module.ModuleName} FileName: {module.FileName}");
}
Lansarea unui nou proces
Cu ajutorul metodei statice Process.Start(), se poate lansa un nou proces. De exemplu:
// lansarea unei aplicații
Process.Start(@"C:\Program Files\Google\Chrome\Application\chrome");
// Process.Start("/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"); // pe MacOS
În acest caz, se lansează browserul Google Chrome.
În cazul lansării unor programe, poate fi necesar să le transmitem diferiți parametri. În acest caz, se poate folosi o versiune suprasolicitată a metodei, unde se transmit parametrii:
Process.Start(@"C:\Program Files\Google\Chrome\Application\chrome", "https://metanit.com");
Pentru a separa configurarea parametrilor de lansare de lansarea propriu-zisă, se poate folosi clasa ProcessStartInfo:
ProcessStartInfo procInfo = new ProcessStartInfo();
// fișierul executabil al programului - browserul Chrome
procInfo.FileName = @"C:\Program Files\Google\Chrome\Application\chrome";
// argumentele de lansare - adresa resursei internet
procInfo.Arguments = "https://metanit.com";
Process.Start(procInfo);
Aceste metode permit gestionarea eficientă a proceselor și resurselor utilizate de aplicațiile .NET.