Системни разговори

Системно обаждане на Linux Exec

Системно обаждане на Linux Exec

Системното повикване exec се използва за изпълнение на файл, който се намира в активен процес. Когато exec бъде извикан, предишният изпълним файл се заменя и се изпълнява нов файл.

По-точно можем да кажем, че използването на системно повикване exec ще замени стария файл или програма от процеса с нов файл или програма. Цялото съдържание на процеса се заменя с нова програма.

Потребителският сегмент от данни, който изпълнява системното повикване exec (), се заменя с файл с данни, чието име е предоставено в аргумента, докато се извиква exec ().

Новата програма се зарежда в същото пространство на процеса. Текущият процес просто се превръща в нов процес и следователно идентификаторът на идентификатора на процеса не се променя, това е така, защото ние не създаваме нов процес, а просто заместваме процес с друг процес в exec.

Ако текущият процес съдържа повече от една нишка, тогава всички нишки ще бъдат прекратени и новото изображение на процеса ще бъде заредено и след това изпълнено. Няма деструкторни функции, които прекратяват нишките на текущия процес.

PID на процеса не се променя, но данните, кодът, стекът, купчината и т.н. от процеса се променят и се заменят с тези на новозареден процес. Новият процес се изпълнява от входната точка.

Exec system call е съвкупност от функции и на програмния език C стандартните имена за тези функции са както следва:

  1. execl
  2. екзекъл
  3. execlp
  4. execv
  5. execve
  6. execvp


Тук трябва да се отбележи, че тези функции имат една и съща основа изпълн последвано от една или повече букви. Те са обяснени по-долу:

д: Това е масив от указатели, който сочи към променливи на околната среда и се предава изрично на новозаредения процес.

л: l е за аргументите от командния ред, предадени списък на функцията

п: p е променливата на средата на пътя, която помага да се намери файлът, предаден като аргумент за зареждане в процеса.

v: v е за аргументите на командния ред. Те се предават като масив от указатели към функцията.

Защо се използва exec?

exec се използва, когато потребителят иска да стартира нов файл или програма в същия процес.

Вътрешна работа на изпълнител

Обмислете следните точки, за да разберете работата на exec:

  1. Текущото изображение на процеса се заменя с ново изображение на процеса.
  2. Новият образ на процеса е този, който сте предали като аргумент exec
  3. Текущият в момента процес е приключил
  4. Новото изображение на процеса има същия идентификатор на процеса, същата среда и същия дескриптор на файла (тъй като процесът не се заменя, изображението на процеса се заменя)
  5. Засегнати са статията на процесора и виртуалната памет. Картографирането на виртуалната памет на текущия образ на процеса се заменя с виртуална памет на новото изображение на процеса.

Синтаксиси на функции на семейството exec:

По-долу са синтаксисите за всяка функция на exec:

int execl (const char * път, const char * arg, ...)
int execlp (файл const char *, const char * arg, ...)
int execle (const char * path, const char * arg,…, char * const envp [])
int execv (const char * path, const char * argv [])
int execvp (файл const char *, const char * argv [])
int execvpe (файл const char *, const char * argv [], char * const envp [])

Описание:

Типът на връщане на тези функции е Int. Когато изображението на процеса бъде успешно заменено, нищо не се връща към извикващата функция, тъй като процесът, който го е извикал, вече не работи. Но ако има някаква грешка -1 ще бъде върната. Ако възникне грешка, грешно е зададено.

В синтаксиса:

  1. път се използва за указване на пълното име на пътя на файла, който трябва да бъде изпълнен.
  1. аргумент е предаденият аргумент. Това всъщност е името на файла, който ще бъде изпълнен в процеса. Повечето пъти стойността на arg и path е една и съща.
  1. const char * арг във функциите execl (), execlp () и execle () се счита за arg0, arg1, arg2,…, argn. Това е основно списък с указатели за нулирани прекратени низове. Тук първият аргумент сочи към името на файла, което ще бъде изпълнено, както е описано в точка 2.
  1. envp е масив, който съдържа указатели, които сочат към променливите на средата.
  1. файл се използва за указване на името на пътя, което ще идентифицира пътя на новия файл с изображение на процеса.
  1. Функциите на exec извикват, които завършват с д се използват за промяна на средата за новия образ на процеса. Тези функции предават списък на настройката на средата, като използват аргумента envp. Този аргумент е масив от символи, който сочи към завършен с нула низ и дефинира променлива на средата.

За да използвате семейните функции на exec, трябва да включите следния заглавен файл във вашата програма на C:

#include

Пример 1: Използване на системно повикване exec в програма C

Помислете за следния пример, в който сме използвали системно повикване exec при програмиране на C в Linux, Ubuntu: Тук имаме два c файла.в и здравей.° С:

пример.° С

КОД:

#include
#include
#include
int main (int argc, char * argv [])

printf ("PID на пример.c =% d \ n ", getpid ());
char * args [] = "Здравей", "C", "Програмиране", NULL;
execv ("./ здравей ", аргументи);
printf ("Назад към примера.° С");
връщане 0;

Здравейте.° С

КОД:

#include
#include
#include
int main (int argc, char * argv [])

printf ("Ние сме в Hello.c \ n ");
printf ("PID на здравей.c =% d \ n ", getpid ());
връщане 0;

ИЗХОД:

PID на пример.с = 4733
Ние сме в Здравейте.° С
PID на здравей.с = 4733

В горния пример имаме пример.c файл и здравей.c файл. В примера .c файл на първо място сме отпечатали идентификатора на текущия процес (пример за файл.c работи в текущия процес). След това в следващия ред сме създали масив от указатели на символи. Последният елемент от този масив трябва да бъде NULL като крайна точка.

След това използвахме функцията execv (), която приема името на файла и масива на показалеца на символи като свой аргумент. Тук трябва да се отбележи, че сме използвали ./ с името на файла, той указва пътя на файла. Тъй като файлът е в папката, където пример.c пребивава, така че няма нужда да указвате пълния път.

Когато се извика функция execv (), образът на процеса ни ще бъде заменен сега, пример за файл.c не е в процес, но файлът здравей.c е в процес. Вижда се, че идентификаторът на процеса е същият, независимо дали здравей.c е изображение на процеса или пример.c е изображение на процеса, тъй като процесът е същият и процесният образ се заменя само.

Тогава имаме още нещо, което трябва да отбележим тук, което е операторът printf (), след като execv () не е изпълнен. Това е така, защото контролът никога не се връща към старото изображение на процеса, след като новото изображение на процеса го замени. Контролът се връща към функцията за извикване само когато замяната на изображението на процеса е неуспешна. (В този случай възвръщаемата стойност е -1).

Разлика между системните повиквания fork () и exec ():

Системното повикване fork () се използва за създаване на точно копие на работещ процес, а създаденото копие е дъщерният процес, а текущият процес е родителският процес. Докато системното повикване exec () се използва за замяна на изображение на процес с ново изображение на процес. Следователно няма концепция за родителски и дъщерни процеси в системното извикване на exec ().

В системното извикване на fork () родителският и дъщерният процес се изпълняват едновременно. Но в системното извикване на exec (), ако замяната на изображението на процеса е успешна, контролата не се връща там, където е била извикана функцията exec, а ще изпълни новия процес. Контролът ще бъде прехвърлен обратно само ако има някаква грешка.

Пример 2: Комбиниране на системни повиквания fork () и exec ()

Да разгледаме следния пример, в който сме използвали системни повиквания fork () и exec () в една и съща програма:

пример.° С

КОД:

#include
#include
#include
int main (int argc, char * argv [])

printf ("PID на пример.c =% d \ n ", getpid ());
pid_t p;
p = вилица ();
ако (p == - 1)

printf ("Има грешка при извикване на fork ()");

ако (p == 0)

printf ("Ние сме в дъщерния процес \ n");
printf ("Здравей.c от дъщерния процес \ n ");
char * args [] = "Здравей", "C", "Програмиране", NULL;
execv ("./ здравей ", аргументи);

друго

printf ("Ние сме в родителския процес");

връщане 0;

Здравейте.° С:

КОД:

#include
#include
#include
int main (int argc, char * argv [])

printf ("Ние сме в Hello.c \ n ");
printf ("PID на здравей.c =% d \ n ", getpid ());
връщане 0;

ИЗХОД:

PID на пример.с = 4790
Ние сме в родителски процес
Ние сме в процес на деца
Здравей.c от детски процес
Ние сме в здравей.° С
PID на здравей.c = 4791

В този пример използвахме системно повикване fork (). Когато се създаде дъщерния процес, 0 ще бъде присвоено на p и след това ще преминем към дъщерния процес. Сега ще бъде изпълнен блокът от изявления с if (p == 0). Показва се съобщение и сме използвали системно повикване execv () и текущото изображение на дъщерния процес, което е пример.c ще бъде заменен с здравей.° С. Преди извикването на execv () процесът дете и родител бяха еднакви.

Вижда се, че PID на пример.в и здравей.c е различно сега. Това е така, защото пример.c е изображението на родителския процес и здравей.c е изображението на дъщерния процес.

Полезни инструменти за геймърите на Linux
Ако искате да играете игри на Linux, има вероятност да сте използвали приложения и помощни програми като Wine, Lutris и OBS Studio, за да подобрите иг...
HD Remastered Games за Linux, които никога преди не са имали издание на Linux
Много разработчици и издатели на игри излизат с HD ремастер на стари игри, за да удължат живота на франчайза, моля феновете, които искат съвместимост ...
Как да използвам AutoKey за автоматизиране на Linux игри
AutoKey е програма за автоматизация на настолни компютри за Linux и X11, програмирана в Python 3, GTK и Qt. Използвайки неговата функционалност за скр...