
// Process.C
Процесс всегда содержит хотя бы один поток. Для процессов исходный код которых подготовлен на языках С/С++, главным потоком процесса является поток, в котором исполняется функция, текстуально описанная под именем main()[15]. Рассмотрим программу, которая получает информацию о значении своих атрибутов (файл process.c):
#include <stdlib.h> // вызов стандартной библиотеки
#include <sys/resourses.h> // статистическая информация о процессе
Int main(int argc, char **argv)
{
struct rusage r_usage; // задается структура последних четырех переметров
printf(“\nProcess Information:\n); // \n – переход на новую строку
printf(“Process name = \t\t%\n”,argv[0]);
// \t – строка, argv[0] – выведем нулевой аргумент (процесс)
printf(“User ID = \t\t<%d>\n”,getuid());
// по аналогии вывод остальной информации
printf(“Effective User ID = \t<%d>\n”,geteuid());
printf(“Group ID = \t\t<%d>\n”,getgid());
printf(“Process Group ID = \t<%d>\n”,getpgid());
printf(“Process ID (PID) = \t<%d>\n”,getpid());
printf(“Parent PID (PPID) = \t<%d>\n”,getppid());
printf(“Process priority = \t<%d>\n”,getprio());
getrusage(RUSAGE_SELF, &r_usage);
printf(‘\t<user time=%d sec, %d microsec >\n’,r_usage, ru_utime,tv_sec,
r_usage, ru_utime,tv_usec);
printf(‘\t<system time=%d sec, %d microsec >\n’,r_usage, ru_stime,tv_sec,
r_usage, ru_stime,tv_usec);
return EXIT_SUCCESS; // завершение работы программы
}
С помощью директивы #include подключаются две библиотки stdlib.h (стандартная библиотека) и sys/resourses.h (статистическая информация о процессе). Программа начинает выполняться с точки входа ‑ функции main().
Параметрами этой функции являются argc – целое значение количества аргументов командной строки при запуске программы и argv – массив, в котором находятся значения этих аргументов. Директива struct rusage задает структуру r_usage для получения информации о статистике выполнения программы. Функция printf() подключаемая через библиотеку stdlib.h обеспечивает вывод на экран сообщений. Управляющий символ \n переводит курсор на новую строку экрана. Переменная argv[0] всегда содержит имя исполняемой программы. Далее в функциях printf() происходит вызов функций для получения соответствующих атрибутов процесса. Функция getrusage(RUSAGE_SELF, &r_usage) возвращает в структуру r_usage информацию о статистике выполнения программы. Оператором return программа завершается и возвращает в создавший ее процесс сообщение EXIT_SUCCESS (имеет значение 0) – успешное завершение.
// Fork.C
Первой из функций пораждения процессов является функция fork() – создает дочерний процесс путем «клонирования» родительского процесса. Действие вызова fork() следующее: порождается дочерний процесс, которому системой присваивается новое уникальное значение PID. Дочерний процесс получает собственные копии файловых дескрипторов, открытых в родительском процессе в точке выполнения fork(). Каждый дескриптор ссылается на тот же файл, который соответствует аналогичному дескриптору родителя. Блокировки файлов (locks), установленные в родительском процессе, наследуются дочерним процессом. При клонировании родительский и дочерний процессы различаются только идентификаторами PID и PPID. Функцию fork() рекомендуется использовать только в однопоточных программах.
Рассмотрим применение функции fork() на примере программы fork.c. Функция fork() возвращает целое число, которое в родительском процессе равно идентификатору PID дочернего процесса, а в дочернем – нулю.
// fork.c
#include <stdlib.h>
#include <sys/syspage.h>
int main(int argc, char **argv, char **env)
// функция возвращает целое значение.
//argc – количство параметров передаваемых функции аргументов,
//argv – сами аргументы, env – сообщения.
{
pid_t pid; // тип данных для хранения идентификатора процесса
char *prefix;
prefix=(char*)malloc(sizeof(char)); // выделение памяти
pid=fork(); // новый процесс, дочерний к родительскому
if (pid==0) sprintf(prefix, ‘child’); // был ли создан дочерний процесс
else sprintf(prefix,”parent’);
printf(“%s Process name =%s\n”,prefix,argv[0]); // вывод информации
printf(“%s PID=%d\n”,prefix,getpid(0));
printf(“%s PPID=%d\n”,prefix,getppid(0));
return EXIT_SUCCESS; // завершение работы программы
}
Функция vfork() (виртуальный fork()) – используется как «облегченная» альтернатива паре вызовов fork()-exec(). В отличии от стандартной функции fork(), она не выполняет реального копирования данных, а просто блокирует родительский процесс, пока дочерний не вызовет exec().