- •Методические указания для выполнения лабораторной работы № 2 по курсу «Операционные системы и системное программирование»
- •Цель работы
- •Краткие теоретические сведения Основные функции стандарта
- •Примеры использования потоков
- •Атрибуты
- •Присоединяемые и оторванные потоки
- •Взаимное исключение потоков
- •Условные переменные
- •Ход работы
- •Содержание отчета
Министерство образования Республики Беларусь
ПОЛОЦКИЙ ГОСУДАРСТВЕННЫЙ УНИВЕРСИТЕТ
Кафедра технологий программирования
Методические указания для выполнения лабораторной работы № 2 по курсу «Операционные системы и системное программирование»
«Потоки в ОС Linux»
Полоцк, 2016
Цель работы
Создание и синхронизация потоков в соответствии с международным стандартом POSIX. Распараллеливания последовательных задач с последующим анализом времени выполнения.
Краткие теоретические сведения Основные функции стандарта
Pthreads определяет набор типов и функций на языке программирования Си. Заголовочный файл — pthread.h.
Типы данных:
pthread_t: дескриптор потока
pthread_attr_t: перечень атрибутов потока
Функции управления потоками:
pthread_create(): создание потока
pthread_exit(): завершение потока (должна вызываться функцией потока при завершении)
pthread_cancel(): отмена потока
pthread_join(): заблокировать выполнение потока до прекращения другого потока, указанного в вызове функции
pthread_detach(): освободить ресурсы занимаемые потоком (если поток выполняется, то освобождение ресурсов произойдёт после его завершения)
pthread_attr_init(): инициализировать структуру атрибутов потока
pthread_attr_setdetachstate(): указать системе, что после завершения потока она может автоматически освободить ресурсы, занимаемые потоком
pthread_attr_destroy(): освободить память от структуры атрибутов потока (уничтожить дескриптор)
Функции синхронизации потоков:
pthread_mutex_init(), pthread_mutex_destroy(), pthread_mutex_lock(), pthread_mutex_trylock(), pthread_mutex_unlock(): с помощью мьютексов
pthread_cond_init(), pthread_cond_signal(), pthread_cond_wait(): с помощью условных переменных
Примеры использования потоков
Пример 1:
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
static void wait_thread(void)
{
time_t start_time = time(NULL);
while (time(NULL) == start_time)
{
// do nothing except chew CPU slices for up to one second.
}
}
static void *thread_func(void *vptr_args)
{
int i;
for (i = 0; i < 20; i++)
{
fputs(" b\n", stderr);
wait_thread();
}
return NULL;
}
int main(void)
{
int i;
pthread_t thread;
if (pthread_create(&thread, NULL, thread_func, NULL) != 0)
{
return EXIT_FAILURE;
}
for (i = 0; i < 20; i++)
{
puts("a");
wait_thread();
}
if (pthread_join(thread, NULL) != 0)
{
return EXIT_FAILURE;
}
return EXIT_SUCCESS;
}
Пример 2:
#include <pthread.h>
#include <stdio.h>
//переменная для сборки окончательного результата
int globalRes = 0;
//векторы, которые предстоит умножить
int v1[100], v2[100];
//
int ids[4] = {0,1,2,3};
//четрыре объекта типа "описатель потока"
pthread_t thrs[4];
//мьютекс
pthread_mutex_t mutex;
//функция потока
void* prod(void* me)
{
//узнали номер потока
int offset = *((int*)me);
//вычислили смещение в векторе до "своей" четверти
offset *= 25;
//вычисление частичного результата
int res = 0;
for(int i = offset; i<offset+25; i++)
res += v1[i]*v2[i];
//захват мьютекса
pthread_mutex_lock(&mutex);
//добавление к глобальному результату при исключительном владении глобальной переменной
globalRes += res;
//освобождение мьютекса
pthread_mutex_unlock(&mutex);
}
int main()
{
//тут где-то должна быть инициализация массивов
//атрибуты потока
pthread_attr_t attrs;
//инициализация атрибутов потока
if(0!=pthread_attr_init(&attrs))
{
perror("Cannot initialize attributes");
abort();
};
//установка атрибута "присоединенный"
if(0!=pthread_attr_setdetachstate(&attrs, PTHREAD_CREATE_JOINABLE))
{
perror("Error in setting attributes");
abort();
}
//порождение четырех потоков
for(int i = 0; i<4; i++)
if(0!=pthread_create(&thrs[i], &attrs, prod, &ids[i]))
{
perror("Cannot create a thread");
abort();
}
//освобождение ресурсов, занимаемых описателем атрибутов
pthread_attr_destroy(&attrs);
//ожидание завершения порожденных потоков
for(int i = 0; i<4; i++)
if(0!=pthread_join(thrs[i], NULL)
{
perror("Cannot join a thread");
abort();
}
return 0;
}