Linux Exec System -puhelu

Linux Exec System Call

Suoritusjärjestelmän kutsua käytetään suorittamaan tiedosto, joka sijaitsee aktiivisessa prosessissa. Kun exec kutsutaan, edellinen suoritettava tiedosto korvataan ja uusi tiedosto suoritetaan.

Tarkemmin sanottuna voimme sanoa, että exec -järjestelmän kutsun käyttäminen korvaa prosessin vanhan tiedoston tai ohjelman uudella tiedostolla tai ohjelmalla. Koko prosessin sisältö korvataan uudella ohjelmalla.



Käyttäjätietosegmentti, joka suorittaa exec () -järjestelmäkutsun, korvataan datatiedostolla, jonka nimi annetaan argumentissa, kun se kutsuu exec () -komentoa.



Uusi ohjelma ladataan samaan prosessitilaan. Nykyinen prosessi on juuri muutettu uudeksi prosessiksi, joten prosessin tunnus PID ei muutu. Tämä johtuu siitä, että emme ole luomassa uutta prosessia, vaan korvaamme prosessin toisella suorituksella.



Jos käynnissä oleva prosessi sisältää useamman kuin yhden säikeen, kaikki säikeet lopetetaan ja uusi prosessikuva ladataan ja suoritetaan. Ei ole tuhoustoimintoja, jotka lopettavat nykyisen prosessin säikeet.

Prosessin PID -arvoa ei muuteta, mutta prosessin tiedot, koodi, pino, kasa jne. Muutetaan ja korvataan vasta ladatun prosessin tiedoilla. Uusi prosessi suoritetaan aloituspisteestä.

Exec -järjestelmäkutsu on kokoelma toimintoja ja C -ohjelmointikielellä näiden toimintojen vakiomerkinnät ovat seuraavat:



  1. suoritus
  2. execle
  3. execlp
  4. execv
  5. suorittaa
  6. execvp


Tässä on huomattava, että näillä toiminnoilla on sama perusta toteuttaja jota seuraa yksi tai useampi kirjain. Nämä selitetään alla:

Ja: Se on joukko osoittimia, jotka osoittavat ympäristömuuttujia ja välitetään nimenomaan äskettäin ladatulle prosessille.

: l on komentorivin argumentit, jotka ovat välittäneet funktiolle luettelon

p: p on polkuympäristömuuttuja, joka auttaa löytämään prosessiin ladattavana argumenttina lähetetyn tiedoston.

v: v on komentoriviargumenteille. Nämä välitetään funktiolle osoitinryhmänä.

Miksi exec käytetään?

exec käytetään, kun käyttäjä haluaa käynnistää uuden tiedoston tai ohjelman samassa prosessissa.

Sisäinen työskentely

Harkitse seuraavia kohtia ymmärtääksesi suorituksen toiminnan:

  1. Nykyinen prosessikuva korvataan uudella prosessikuvalla.
  2. Uusi prosessikuva on se, jonka annoit suoritusargumenttina
  3. Tällä hetkellä käynnissä oleva prosessi on päättynyt
  4. Uudella prosessikuvalla on sama prosessitunnus, sama ympäristö ja sama tiedostonkuvaaja (koska prosessia ei korvata prosessikuva korvataan)
  5. Tämä vaikuttaa suorittimen tilaan ja virtuaalimuistiin. Nykyisen prosessikuvan virtuaalimuistikartoitus korvataan uuden prosessikuvan virtuaalimuistilla.

Exec -perhefunktioiden syntaksit:

Seuraavat ovat syntakseja jokaiselle exec -toiminnolle:

int execl (const char* polku, const char* arg,…)
int execlp (const char* tiedosto, const char* arg,…)
int execle (const char* polku, const char* arg,…, char* const envp [])
int execv (const char* polku, const char* argv [])
int execvp (const char* tiedosto, const char* argv [])
int execvpe (const char* tiedosto, const char* argv [], char* const envp [])

Kuvaus:

Näiden toimintojen palautustyyppi on Int. Kun prosessikuva on korvattu onnistuneesti, mitään ei palauteta kutsutoimintoon, koska sitä kutsunut prosessi ei ole enää käynnissä. Mutta jos on virhe, -1 palautetaan. Jos tapahtuu virhe, a errno on asetettu.

Syntaksissa:

  1. polku käytetään määrittämään suoritettavan tiedoston koko polun nimi.
  1. vihainen onko argumentti hyväksytty. Se on itse asiassa tiedoston nimi, joka suoritetaan prosessissa. Useimmiten arg ja path arvo ovat samat.
  1. const char* arg funktioissa execl (), execlp () ja execle () pidetään arg0, arg1, arg2,…, argn. Se on pohjimmiltaan luettelo osoittimista lopetettujen merkkijonojen nollaamiseen. Tässä ensimmäinen argumentti viittaa tiedostonimeen, joka suoritetaan kohdassa 2 kuvatulla tavalla.
  1. envp on taulukko, joka sisältää ympäristömuuttujia osoittavia osoittimia.
  1. tiedosto käytetään määrittämään polun nimi, joka tunnistaa uuden prosessikuvatiedoston polun.
  1. Funktiot exec kutsuvat, jotka päättyvät Ja käytetään uuden prosessikuvan ympäristön muuttamiseen. Nämä toiminnot läpäisevät ympäristön asetusluettelon argumentin avulla envp . Tämä argumentti on merkkijono, joka viittaa nollapäätteiseen merkkijonoon ja määrittelee ympäristömuuttujan.

Jos haluat käyttää exec -perheen toimintoja, sinun on sisällytettävä seuraava otsikkotiedosto C -ohjelmaan:

#sisältää

Esimerkki 1: Exec -järjestelmän kutsun käyttäminen C -ohjelmassa

Harkitse seuraavaa esimerkkiä, jossa olemme käyttäneet exec -järjestelmän kutsua C -ohjelmoinnissa Linuxissa, Ubuntussa: Meillä on kaksi c -tiedostoa tässä esimerkki.c ja hello.c:

esimerkki. c

KOODI:

#sisältää
#sisältää
#sisältää
inttärkein(intargc, hiiltyä *argv[])
{
printf ('Esimerkin PID. C = %d n'',hölmö());
hiiltyä *args[] = {'Hei', 'C', 'Ohjelmointi',TYHJÄ};
execv('./Hei',args);
printf ('Takaisin esimerkkiin. C');
palata 0;
}

hei C

KOODI:

#sisältää
#sisältää
#sisältää
inttärkein(intargc, hiiltyä *argv[])
{
printf ('Olemme Hello.c: ssä n'');
printf ('Hei PID. C = %d n'',hölmö());
palata 0;
}

LÄHTÖ:

Esimerkin PID. C = 4733
Olemme Hello.c: ssä
Hei PID. C = 4733

Yllä olevassa esimerkissä meillä on example.c -tiedosto ja hello.c -tiedosto. Esimerkissä .c -tiedostossa on ensin tulostettu nykyisen prosessin tunnus (tiedosto example.c on käynnissä nykyisessä prosessissa). Sitten seuraavalla rivillä olemme luoneet joukon merkkikohdistimia. Tämän taulukon viimeisen elementin tulisi olla päätepiste NULL.

Sitten olemme käyttäneet funktiota execv (), joka käyttää tiedoston nimeä ja merkkikohdetaulukkoa argumenttinaan. Tässä on huomattava, että olemme käyttäneet ./ tiedoston nimen kanssa, se määrittää tiedoston polun. Koska tiedosto on kansiossa, jossa esimerkki.c sijaitsee, koko polkua ei tarvitse määrittää.

Kun execv () -funktiota kutsutaan, prosessikuvaamme korvataan nyt tiedostolla example.c ei ole prosessissa, mutta tiedosto hello.c on prosessissa. Voidaan nähdä, että prosessitunnus on sama riippumatta siitä, onko hello.c prosessikuva tai esimerkki. C on prosessikuva, koska prosessi on sama ja prosessikuva on vain korvattu.

Sitten meillä on vielä yksi huomioitava asia, joka on printf () -lause sen jälkeen, kun execv () ei suoriteta. Tämä johtuu siitä, että ohjausta ei koskaan palauteta takaisin vanhaan prosessikuvaan, kun uusi prosessikuva on korvannut sen. Ohjaus palaa puhelutoimintoon vasta, kun prosessikuvan vaihtaminen ei onnistu. (Palautusarvo on tässä tapauksessa -1).

Ero haarukan () ja exec () -järjestelmäkutsujen välillä:

Haarukan () järjestelmäkutsua käytetään luomaan tarkka kopio käynnissä olevasta prosessista, ja luotu kopio on aliprosessi ja käynnissä oleva prosessi on pääprosessi. Järjestelmäkutsua exec () käytetään prosessikuvan korvaamiseen uudella prosessikuvalla. Näin ollen exec () -järjestelmäkutsussa ei ole käsitettä vanhemman ja aliprosessista.

Fork () -järjestelmäkutsussa vanhempi- ja aliprosessit suoritetaan samanaikaisesti. Mutta exec () -järjestelmäkutsussa, jos prosessikuvan korvaaminen onnistuu, ohjaus ei palaa sinne, missä exec -funktio kutsuttiin, vaan suorittaa uuden prosessin. Ohjaus siirretään takaisin vain, jos on virhe.

Esimerkki 2: Haarukoiden () ja exec () järjestelmäkutsujen yhdistäminen

Harkitse seuraavaa esimerkkiä, jossa olemme käyttäneet sekä fork () - että exec () -järjestelmäkutsuja samassa ohjelmassa:

esimerkki. c

KOODI:

#sisältää
#sisältää
#sisältää
inttärkein(intargc, hiiltyä *argv[])
{
printf ('Esimerkin PID. C = %d n'',hölmö());
pid_t s;
s=haarukka();
jos(s== -1)
{
printf ('Virhe soitettaessa haarukkaan ()');
}
jos(s==0)
{
printf ('Olemme lapsiprosessissa n'');
printf ('Soittaminen hei.c: lle lapsiprosessista n'');
hiiltyä *args[] = {'Hei', 'C', 'Ohjelmointi',TYHJÄ};
execv('./Hei',args);
}
muu
{
printf ('Olemme vanhempainprosessissa');
}
palata 0;
}

hei C:

KOODI:

#sisältää
#sisältää
#sisältää
inttärkein(intargc, hiiltyä *argv[])
{
printf ('Olemme Hello.c: ssä n'');
printf ('Hei PID. C = %d n'',hölmö());
palata 0;
}

LÄHTÖ:

Esimerkin PID. C = 4790
Olemme isäprosessissa
Olemme lapsiprosessissa
Soittaminen hello.c: lle lapsiprosessista
Olemme hei. C
Hei PID. C = 4791

Tässä esimerkissä olemme käyttäneet fork () -järjestelmäkutsua. Kun aliprosessi on luotu, p: lle annetaan 0 ja siirrymme sitten aliprosessiin. Nyt suoritetaan lausekkeiden lohko, jossa if (p == 0). Näyttöön tulee viesti, ja olemme käyttäneet execv () -järjestelmäpuhelua ja nykyistä aliprosessikuvaa, joka on esimerkki. C korvataan sanalla hello.c. Ennen execv () -puhelua lapsen ja vanhemman prosessit olivat samat.

On nähtävissä, että esimerkin c ja hello.c PID on nyt erilainen. Tämä johtuu siitä, että esimerkki.c on pääprosessikuva ja hei.c on aliprosessikuva.