Linux izpildes sistēmas zvans

Linux Exec System Call



Izpildes sistēmas izsaukums tiek izmantots, lai izpildītu failu, kas atrodas aktīvā procesā. Kad tiek saukta izpilde, tiek aizstāts iepriekšējais izpildāmais fails un tiek izpildīts jauns fails.

Precīzāk, mēs varam teikt, ka, izmantojot izpildes sistēmas zvanu, vecais fails vai programma no procesa tiks aizstāta ar jaunu failu vai programmu. Viss procesa saturs tiek aizstāts ar jaunu programmu.







Lietotāja datu segments, kas izpilda izpildes () sistēmas izsaukumu, tiek aizstāts ar datu failu, kura nosaukums ir norādīts argumentā, kamēr tiek izsaukts exec ().



Jaunā programma tiek ielādēta tajā pašā procesa telpā. Pašreizējais process ir tikko pārvērsts par jaunu procesu, un līdz ar to procesa ID PID netiek mainīts, tas ir tāpēc, ka mēs neradām jaunu procesu, mēs vienkārši aizstājam procesu ar citu izpildes procesu.



Ja pašlaik notiekošajā procesā ir vairāk nekā viens pavediens, tad visi pavedieni tiks pārtraukti un jaunais procesa attēls tiks ielādēts un pēc tam izpildīts. Nav destruktoru funkciju, kas izbeigtu pašreizējā procesa pavedienus.





Procesa PID netiek mainīts, bet tiek mainīti procesa dati, kods, kaudze, kaudze utt., Un tie tiek aizstāti ar nesen ielādētā procesa datiem. Jaunais process tiek izpildīts no ieejas punkta.

Izpildīt sistēmas zvanu ir funkciju kopums, un C programmēšanas valodā šo funkciju standarta nosaukumi ir šādi:



  1. izpildīt
  2. ekseleklis
  3. izpildīt
  4. izpild
  5. izpildīt
  6. izpildītājs


Šeit jāatzīmē, ka šīm funkcijām ir vienāda bāze izpildītājs kam seko viens vai vairāki burti. Tie ir izskaidroti tālāk:

Un: Tas ir rādītāju masīvs, kas norāda uz vides mainīgajiem un tiek nepārprotami nodots tikko ielādētajam procesam.

: l ir komandrindas argumenti, kas funkcijai nodeva sarakstu

p: p ir ceļa vides mainīgais, kas palīdz atrast failu, kas nodots kā arguments, kas jāielādē procesā.

v: v ir paredzēts komandrindas argumentiem. Tie tiek nodoti funkcijai kā norāžu masīvs.

Kāpēc tiek izmantota exec?

exec tiek izmantots, ja lietotājs tajā pašā procesā vēlas palaist jaunu failu vai programmu.

Izpildītāja iekšējā darbība

Lai saprastu izpildītāja darbību, apsveriet šādus punktus:

  1. Pašreizējais procesa attēls tiek pārrakstīts ar jaunu procesa attēlu.
  2. Jauns procesa attēls ir tas, kuru jūs izmantojāt kā izpildes argumentu
  3. Pašreizējais process ir beidzies
  4. Jaunajam procesa attēlam ir tāds pats procesa ID, tāda pati vide un tas pats faila apraksts (jo process netiek aizstāts, procesa attēls tiek aizstāts)
  5. Tiek ietekmēts CPU statuss un virtuālā atmiņa. Pašreizējā procesa attēla virtuālās atmiņas kartēšanu aizstāj ar jauna procesa attēla virtuālo atmiņu.

Izpildes ģimenes funkciju sintakse:

Tālāk ir sniegta katras izpildfunkcijas sintakse:

int execl (const char* ceļš, const char* arg,…)
int execlp (const char* fails, const char* arg,…)
int execle (const char* ceļš, const char* arg,…, char* const envp [])
int execv (const char* ceļš, const char* argv [])
int execvp (const char* fails, const char* argv [])
int execvpe (const char* fails, const char* argv [], char* const envp [])

Apraksts:

Šo funkciju atgriešanas veids ir Int. Kad procesa attēls ir veiksmīgi nomainīts, nekas netiek atgriezts zvanīšanas funkcijai, jo process, kas to izsauca, vairs nedarbojas. Bet, ja ir kāda kļūda --1 tiks atgriezta. Ja rodas kāda kļūda an kļūda ir iestatīts.

Sintaksē:

  1. ceļš tiek izmantots, lai norādītu izpildāmā faila pilnu ceļa nosaukumu.
  1. dusmīgs vai arguments ir pieņemts. Faktiski tas ir faila nosaukums, kas tiks izpildīts procesā. Lielākoties arg un path vērtība ir vienāda.
  1. const char* arg funkcijās execl (), execlp () un execle () tiek uzskatīti par arg0, arg1, arg2,…, argn. Tas būtībā ir saraksts ar norādēm, lai atceltu pārtrauktas virknes. Šeit pirmais arguments norāda uz faila nosaukumu, kas tiks izpildīts, kā aprakstīts 2. punktā.
  1. envp ir masīvs, kas satur norādes, kas norāda uz vides mainīgajiem.
  1. failu tiek izmantots, lai norādītu ceļa nosaukumu, kas identificēs jaunā procesa attēla faila ceļu.
  1. Izpildes funkcijas izsauc, kas beidzas ar Un tiek izmantoti, lai mainītu vidi jaunajam procesa attēlam. Šīs funkcijas iziet vides iestatījumu sarakstu, izmantojot argumentu envp . Šis arguments ir rakstzīmju masīvs, kas norāda uz virkni, kas beidzas ar nulli, un definē vides mainīgo.

Lai izmantotu izpildes ģimenes funkcijas, C programmā jāiekļauj šāds galvenes fails:

#iekļaut

1. piemērs: Izpildes sistēmas izsaukuma izmantošana C programmā

Apsveriet šādu piemēru, kurā mēs esam izmantojuši izpildes sistēmas izsaukumu C programmēšanā Linux, Ubuntu: Mums ir divi c faili šeit example.c un hello.c:

piemērs.c

KODS:

#iekļaut
#iekļaut
#iekļaut
intgalvenais(intargc, char *argv[])
{
printf ('Piemēra PID. C = %d n',stulbs());
char *args[] = {'Sveiki', “C”, 'Programmēšana',NULL};
izpild('./Sveiki',args);
printf ('Atpakaļ pie piemēra.c');
atgriezties 0;
}

sveiki.c

KODS:

#iekļaut
#iekļaut
#iekļaut
intgalvenais(intargc, char *argv[])
{
printf ('Mēs esam Hello.c n');
printf ('Sveiki, PID. C = %d n',stulbs());
atgriezties 0;
}

Izeja:

Piemēra PID. C = 4733
Mēs atrodamies Hello.c
Sveiciena PID.c = 4733

Iepriekš minētajā piemērā mums ir fails example.c un hello.c fails. .C faila piemērā vispirms esam izdrukājuši pašreizējā procesa ID (fails example.c darbojas pašreizējā procesā). Tad nākamajā rindā mēs esam izveidojuši rakstzīmju rādītāju masīvu. Šī masīva pēdējam elementam kā beigu punktam jābūt NULL.

Tad mēs esam izmantojuši funkciju execv (), kas kā argumentu ņem faila nosaukumu un rakstzīmju rādītāju masīvu. Šeit jāatzīmē, ka mēs esam izmantojuši ./ ar faila nosaukumu, tas norāda faila ceļu. Tā kā fails atrodas mapē, kurā atrodas example.c, nav nepieciešams norādīt pilnu ceļu.

Kad tiek izsaukta funkcija execv (), mūsu procesa attēls tiks aizstāts tagad. Var redzēt, ka procesa ID ir vienāds neatkarīgi no tā, vai hello.c ir procesa attēls vai piemērs. C ir procesa attēls, jo process ir vienāds un procesa attēls tiek aizstāts tikai.

Tad mums ir jāatzīmē vēl viena lieta, kas ir paziņojums printf () pēc tam, kad execv () nav izpildīts. Tas notiek tāpēc, ka vadība nekad netiek atgriezta pie vecā procesa attēla, tiklīdz to aizstāj jauns procesa attēls. Vadība atgriežas zvanīšanas funkcijā tikai tad, ja procesa attēla nomaiņa ir neveiksmīga. (Atgriešanās vērtība šajā gadījumā ir -1).

Atšķirība starp fork () un exec () sistēmas zvaniem:

Sistēmas izsaukums fork () tiek izmantots, lai izveidotu precīzu tekoša procesa kopiju, un izveidotā kopija ir pakārtotais process, un darbības process ir vecāku process. Tā kā sistēmas izsaukums exec () tiek izmantots, lai procesa attēlu aizstātu ar jaunu procesa attēlu. Tādējādi izpildes () sistēmas izsaukumā nav vecāku un bērnu procesu jēdziena.

Fork () sistēmas izsaukumā vecāku un pakārtotie procesi tiek izpildīti vienlaicīgi. Bet izpildes () sistēmas izsaukumā, ja procesa attēla nomaiņa ir veiksmīga, vadīkla neatgriežas vietā, kur tika izsaukta izpildes funkcija, drīzāk tā izpildīs jauno procesu. Vadība tiks nodota atpakaļ tikai tad, ja ir kāda kļūda.

2. piemērs. Dakšas () un exec () sistēmas zvanu apvienošana

Apsveriet šādu piemēru, kurā vienā programmā esam izmantojuši gan fork (), gan exec () sistēmas izsaukumus:

piemērs.c

KODS:

#iekļaut
#iekļaut
#iekļaut
intgalvenais(intargc, char *argv[])
{
printf ('Piemēra PID. C = %d n',stulbs());
pid_t lpp;
lpp=dakša();
ja(lpp== -1)
{
printf ('Zvanot uz dakšu (), radās kļūda');
}
ja(lpp==0)
{
printf ('Mēs esam bērna procesā n');
printf ('Zvanot hello.c no bērna procesa n');
char *args[] = {'Sveiki', “C”, 'Programmēšana',NULL};
izpild('./Sveiki',args);
}
citādi
{
printf ('Mēs esam vecāku procesā');
}
atgriezties 0;
}

sveiki.c:

KODS:

#iekļaut
#iekļaut
#iekļaut
intgalvenais(intargc, char *argv[])
{
printf ('Mēs esam Hello.c n');
printf ('Sveiki, PID. C = %d n',stulbs());
atgriezties 0;
}

Izeja:

Piemēra PID. C = 4790
Mēs esam vecāku procesā
Mēs esam bērna procesā
Zvana hello.c no bērna procesa
Mēs esam sveicināti.c
Sveiciena PID.c = 4791

Šajā piemērā mēs esam izmantojuši fork () sistēmas izsaukumu. Kad bērna process ir izveidots, 0 tiks piešķirts p, un tad mēs pāriesim pie bērna procesa. Tagad tiks izpildīts paziņojumu bloks ar if (p == 0). Tiek parādīts ziņojums, un mēs esam izmantojuši execv () sistēmas zvanu un pašreizējo bērnu procesa attēlu, kas ir example.c tiks aizstāts ar hello.c. Pirms execv () zvana bērna un vecāku procesi bija vienādi.

Var redzēt, ka example.c un hello.c PID tagad atšķiras. Tas ir tāpēc, ka piemērs.c ir vecāka procesa attēls, un sveiki. C ir bērna procesa attēls.