МНОГОЗАДАЧНОЕ ПРОГРАММИРОВАНИЕ В LINUX
Поможем в ✍️ написании учебной работы
Поможем с курсовой, контрольной, дипломной, рефератом, отчетом по практике, научно-исследовательской и любой другой работой

 

1. Цель работы: Ознакомиться с компилятором gcc, методикой отладки программ, функциями работы с процессами.

 

Краткие теоретические сведения.

Минимальным набором ключей компилятора gcc являются -Wall (выводить все ошибки и предупреждения) и -o (output file):

gcc -Wall -o print_pid print_pid.c

Команда создаст исполняемый файл print_pid.

Стандартная библиотека C (libc, реализованная в Linux в glibc), использует возможности многозадачности Unix System V (далее SysV). В libc тип pid_t определен как целое, способное вместить в себе pid. Функция, которая сообщает pid текущего процесса, имеет прототип pid_t getpid (void) и определена вместе с pid_t в unistd.h и sys/types.h).

Для создания нового процесса используется функция fork:

pid_t fork(void)

Вставляя задержку случайной длины при помощи функций sleep и rand, можно нагляднее увидеть эффект многозадачности:

sleep(rand()%4)

это заставит программу "заснуть" на случайное число секунд: от 0 до 3.

Чтобы в качестве дочернего процесса вызвать функцию, достаточно вызвать ее после ветвления:

pid = fork();

if (pid == 0) {

// если выполняется дочерний процесс, то вызовем функцию

pid=process(arg);

// выход из процесса

exit(0);

Часто в качестве дочернего процесса необходимо запускать другую программу. Для этого применяется функции семейства exec:

pid = fork();

if (pid == 0) {

// если выполняется дочерний процесс, то вызов программы

 if (execl("./file","file",arg, NULL)<0) {

 printf("ERROR while start process\n");

 exit(-2);

 }

 else printf( "process started (pid=%d)\n", pid);

// выход из процесса

}

Часто родительскому процессу необходимо обмениваться информацией с дочерними или хотя бы синхронизироваться с ними, чтобы выполнять операции в нужное время. Один из способов синхронизации процессов — функции wait и waitpid:

#include <sys/types.h>

#include <sys/wait.h>

pid_t wait(int *status) - приостанавливает выполнение текущего процесса до завершения какого-либо из его процессов-потомков.

pid_t waitpid (pid_t pid, int *status, int options) - приостанавливает выполнение текущего процесса до завершения заданного процесса или проверяет завершение заданного процесса.

Если необходимо узнать состояние порожденного процесса при его завершении и возвращенное им значение, то используют макрос WEXITSTATUS, передавая ему в качестве параметра статус дочернего процесса.

status=waitpid(pid,&status,WNOHANG);

if (pid == status) {

printf("PID: %d, Result = %d\n", pid, WEXITSTATUS(status)); }

Для изменения приоритетов порожденных процессов используются функции setpriority и . Приоритеты задаются в диапазоне от -20 (высший) до 20 (низший), нормальное значение - 0. Заметим, что повысить приоритет выше нормального может только суперпользователь!

#include <sys/time.h>

#include <sys/resource.h>

int process( int i) {

setpriority(PRIO_PROCESS, getpid(),i);

printf("Process %d ThreadID: %d working with priority %d\n",i, getpid(),getpriority(PRIO_PROCESS,getpid()));

return(getpriority(PRIO_PROCESS,getpid()));

}

Для уничтожения процесса служит функция kill:

#include <sys/types.h>

#include <signal.h>

int kill(pid_t pid, int sig);

Если pid > 0, то он задает PID процесса, которому посылается сигнал. Если pid = 0, то сигнал посылается всем процессам той группы, к которой принадлежит текущий процесс.

sig - тип сигнала. Некоторые типы сигналов в Linux:

SIGKILL Этот сигнал приводит к немедленному завершению процесса. Этот сигнал процесс не может игнорировать.

SIGTERM Этот сигнал является запросом на завершение процесса.

SIGCHLD Система посылает этот сигнал процессу при завершении одного из его дочерних процессов. Пример:

if (pid[i] == status) {

printf("ThreadID: %d finished with status %d\n", pid[i], WEXITSTATUS(status));

}

else kill(pid[i],SIGKILL);

 

Методические указания.

3.1. Для ознакомления с опциями компилятора gcc, описанием функций языка С используйте инструкции man и info.

3.2. Для отладки программ удобно использовать встроенный редактор файлового менеджера Midnight Commander (MC), выделяющий цветом различные языковые конструкции и указывающий в верхней строке экрана положение курсора в файле (строка, столбец).

3.3. В файловом менеджере Midnight Commander имеется буфер команд, вызываемый сочетанием клавиш <ESС> - H, перемещение по которому производится стрелками управления курсором (вверх и вниз). Для вставки команды из буфера в командную строку используется клавиша <Enter>, для редактирования команды из буфера - клавиши <- и ->, <BackSpace> и <Delete>.

3.4. Помните, что текущая директория не содержится в path, поэтому из командной строки необходимо запускать программу как "./print_pid". В MC достаточно навести курсор на файл и нажать <Enter>.

3.5. Для просмотра результата выполнения программы используйте сочетание клавиш <Ctrl> - O. Они работают и в режиме редактирования файла.

3.6. Для протоколирования результатов выполнения программ целесообразно использовать перенаправление вывода с консоли в файл: ./test > result.txt

3.7. Для доступа к файлам, созданным на сервере Linux, применяйте протокол ftp, клиентская программа которого имеется в Windows 2000 и встроена в файловый менеджер FAR. При этом учетная запись и пароль те же, что и при подключении по протоколу ssh.

 

Порядок выполнения работы.

4.1. Ознакомиться с опциями компилятора gcc, методикой отладки программ.

4.2. Для вариантов заданий из лабораторной работы №1 написать и отладить программу, реализующую порожденный процесс.

4.3. Для вариантов заданий из лабораторной работы №1 написать и отладить программу, реализующую родительский процесс, вызывающий и отслеживающий состояние порожденных процессов - программ (ждущий их завершения или уничтожающий их, в зависимости от варианта).

4.4. Для вариантов заданий из лабораторной работы №1 написать и отладить программу, реализующую родительский процесс, вызывающий и отслеживающий состояние порожденных процессов - функций (ждущий их завершения или уничтожающий их, в зависимости от варианта).

 

5. Варианты заданий. См. варианты заданий из лабораторной работы №1

Содержание отчета.

6.1. Цель работы.

6.2. Вариант задания.

6.3. Листинги программ.

6.4. Протоколы выполнения программ.

 

7. Контрольные вопросы.

7.1. Особенности компиляции и запуска С-программ в Linux.

7.2. Что такое pid, как его определить в операционной системе и программе?

7.3. Функция fork - назначение, применение, возвращаемое значение.

7.4. Как запустить на выполнение в порожденном процессе функцию? Программу?

7.5. Способы синхронизации родительского и дочерних процессов.

7.6. Как узнать состояние порожденного процесса при его завершении и возвращенное им значение?

7.7. Как управлять приоритетами процессов?

7.8. Как уничтожить процесс в операционной системе и программе?

 

ЛАБОРАТОРНАЯ РАБОТА №4

Дата: 2019-12-22, просмотров: 194.