Смекни!
smekni.com

Методические указания к лабораторным работам для студентов IV (стр. 4 из 4)

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. Порядок выполнения работы.

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

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

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

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

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

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

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

ПОТОКИ И ИХ СИНХРОНИЗАЦИЯ В LINUX

1. Цель работы: Освоить функции создания потоков и синхронизации их при помощи взаимных исключений.

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

Взаимное исключение (mutex) является простейшей формой синхронизации. Оно используется для защиты критической области (critical region), предотвращая одновременное выполнение участка кода несколькими потоками (если взаимное исключение используется потоками) или процессами (если взаимное исключение пользуется несколькими процессами). Выглядит это обычно следующим образом.

блокировать_mutex( );

критическая область

разблокировать_mutex(. );

Поскольку только один поток может заблокировать взаимное исключение в любой момент времени, это гарантирует, что только один поток будет выполнять код, относящийся к критической области.

Взаимные исключения по стандарту Posix объявлены как переменные с типом pthread_mutex_t. Если переменная-исключение выделяется статически, ее можно инициализировать константой PTHREAD_MUTEX_INITIALIZER:

static pthread_mutex_t lock=PTHREAD_MUTEX_INITIALIZER;

При динамическом выделении памяти под взаимное исключение (например, вызовом malloc) мы должны инициализировать эту переменную во время выполнения, вызвав функцию pthread_mutex_init.

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

#include <pthread.h>

int pthread_mutex_lock(pthread_mutex_t *mptr);

int pthread_mutex_trylock(pthread_mutex_t *mptr);

int pthread_mutex_unlock(pthread_mutex_t *mptr);

Все три возвращают 0 в случае успешного завершения положительное значение Еххх - в случае ошибки.

При попытке заблокировать взаимное исключение, которое уже заблокировано другим потоком, функция pthread_mutex_lock будет ожидать его разблокирования, a pthread_mutex_trylock (неблокируемая функция) вернет ошибку с кодом BUSY.

Одна из классических задач на синхронизацию называется задачей производителя и потребителя. Один или несколько производителей (потоков или процессов) создают данные, которые обрабатываются одним или несколькими потребителями. Эти данные передаются между производителями и потребителями с помощью одной из форм IPC. Схема рассматриваемого примера изображена на рис. 4.1.

Рис. 4.1. Производители и потребитель

В одном процессе имеется несколько потоков-производителей и один поток-потребитель. Целочисленный массив buff содержит производимые и потребляемые данные (данные совместного пользования) Для простоты производители просто устанавливают значение buff[0] в 0, buff[1] в 1 и т. д. Потребитель перебирает элементы массива, проверяя правильность записей. Поток-потребитель не будет запущен, пока все производители не завершат свою работу. Ниже приведена функция main этого примера.

//mutex/prodcons.с

#define MAXNITEMS 1000000

#define MAXNTHREADS 100

int nitems;/*только для чтения потребителем и производителем*/

struct {

pthread_mutex_t mutex;

int buff[MAXNITEMS];

int nput;

int nval;

} shared = {

PTHREAD_MUTEX_INITIALIZER

};

void *produce(void *), *consume(void *);

int main(int argc, char **argv)

{

int i, nthreads count[MAXNTHREADS];

pthread_t tid_produce[MAXNTHREADS], tid_consume;

if (argc != 3)

err_quit("usage: prodcons3 <#items> <#threads>");

nitems = min(atoi(argv[1]), MAXNITEMS).

nthreads = min(atoi(argv[2]) MAXNTHREADS)

/* создание всех производителей и одного потребителя */

for (i=0; i < nthreads; i++) {

count[i] = 0;

pthread_create(&tid_produce[i] NULL, produce. &count[i];

}

pthread_create(&tid_consume, NULL, consume, NULL);

/* ожидание завершения производителей и потребителя */

for (i= 0; i < nthreads; i++) {

pthread_join(tid_produce[i], NULL);

printf("count[%d] =%d&bsol;n", i, count[i]);

}

pthread_join(tid_consume, NULL);

exit(0);

}

Программа ожидает завершения работы всех потоков-производителей, выводя содержимое счетчика для каждого потока, и потока-потребителя. Ниже приведен текст функций produce и consume:

//mutex/prodcons.с

void *produce(void *arg)

{

for ( ; ; ) {

pthread_mutex_lock(&shared.mutex);

if (shared.nput >= nitems) {

pthread_mutex_unlock(&shared.mutex):

return(NULL); /* массив полный, готово */

}

shared.buff[shared.nput] = shared.nval;

shared.nput++;

shared nva1++;

pthread_mutex unlock(&shared mutex);

*((int *) arg += 1;

}

}

void consume_wait(int i)

{

for ( ;; ) {

pthread_mutex_lock(&shared.mutex);

if (i <shared.nput) {

pthread_mutex_unlock(&shared.mutex);

return; /* элемент готов */

}

pthread_mutex_unlock(&shared.mutex);

}

}

void *consume(void *arg)

{

int i;

for (i = 0; i < nitems; i++) {

consume_wait(i);

if (shared.buff[i] != i)

printf("buff[%d]=%d&bsol;n" i, shared.buff[i]);

}

return(NULL);

}

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

3.1. Для уточнения списка заголовочных файлов, необходимых для вызова функций библиотеки pthread используйте инструкции man и info.

3.2. Хотя функции работы с потоками описаны в файле включения pthread.h, на самом деле они находятся в библиотеке. Поэтому процесс компиляции и сборки многопоточной программы выполняется в два этапа, например:

gcc -Wall -c -o test.o test.c

gcc -Wall -o test test.o <path>libgcc.a –lpthread

3.3. Библиотеку libgcc.a рекомендуется скопировать в текущий каталог.

3.4. Для поиска библиотеки средствами файлового менеджера Midnight Commander используйте сочетание клавиш <Alt> - <Shift> - ?

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

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

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

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

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

4.2. Добавить в написанную программу синхронизацию обращения потоков к какому-либо общему ресурсу, используя взаимные исключения.

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

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

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

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

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

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

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

7.1. Чем потоки отличаются от процессов?

7.2. Функции создания и завершения потоков.

7.3. Зачем и когда необходимо присоединять (join) потоки? Когда и как без этого можно обойтись?

7.4. Атрибуты потоков.

7.5. Что такое мьютекс?

7.6. Особенности инициализации взаимных исключений.

7.7. Чем отличаются функции pthread_mutex_trylock и pthread_mutex_unlock?

7.8. Когда применение мьютексов не гарантирует синхронизации потоков?
Литература

1. Гордеев А.В., Молчанов А.Ю. Системное программное обеспечение. - СПб.: Питер, 2002. – 736 с.

2. Кейлингерт П. Элементы операционных систем. Введение для пользователей /Пер. с англ. - М.: Мир, 1985. - 295 с.

3. Олифер Н.А., Олифер В.Г. Сетевые операционные системы. - СПб.: Питер, 2001.- 560 с.

4. Эпплман Д. Win32 API и Visual Basic. - СПб.: САМС, 2001. – 962 с.

5. Робачевский А.М. Операционная система UNIX. - СПб.: BHV, 1997. - 528 с.

6. Стахнов А.А. LINUX. - СПб.: BHV-Петербург, 2003. - 912 с.

7. Эндрюс Г. Р. Основы многопоточного, параллельного и распределенного программирования. - М.: Вильямс, 2003. - 512 с.

8. Хоар Ч. Взаимодействующие последовательные процессы. - М.: Мир, 1989. - 264 с.

9. Стивенс У. UNIX: взаимодействие процессов. - СПб.: Питер, 2002. - 576 с.


СИСТЕМНОЕ ПРОГРАММНОЕ ОБЕСПЕЧЕНИЕ

Методические указания к лабораторным работам

Редактор

Технический редактор

Лицензия № 021040 от 22.02.96. Подписано в печать ___.___.___.
Формат 60 х 84 1/16. Бумага оберточная. Тираж
150 экз.
Уч.-изд.л. 1,0. Печ.л. 1. Изд. № ______. Заказ № ______ Цена договорная

Отпечатано в типографии

Новосибирского государственного технического университета

630092, г. Новосибирск, пр. К. Маркса, 20