NetNado
  Найти на сайте:

Учащимся

Учителям



Отчет по лабораторной работе №3 по дисциплине «Операционные системы»



Национальный исследовательский

Томский Политехнический университет

Институт – Кибернетический Центр

Направление – Информатика и вычислительная техника

Кафедра – Оптимизации систем управления

«ПРАКТИЧЕСКОЕ ЗНАКОМСТВО С ПОТОКАМИ
И СИНХРОНИЗАЦИЕЙ ПОТОКОВ В ОС UNIX»

Отчет по лабораторной работе № 3
по дисциплине «Операционные системы»

Выполнил

Студент группы 8в83 ___________ А.В. Колчанов


Проверил ___________ Д. В. Сидоров
Томск 2011

Цель работы

Ознакомиться с подсистемой управления потоками в операционной системе Unix и основными программными средствами для создания, управления и удаления потоков.
Задание

Изучить основные программные средства управления потоками ОС Unix, а также способы синхронизации потоков. Разработать приложения для многопоточных вычислений с использованием синхронизации посредством мьютексов, семафоров и условных переменных.

Выполнение работы

2. Разработать три многопоточные программы с использованием минимум двух потоков и различных средств синхронизации. Например: два потока записывают и читают информацию из одного файла; два потока увеличивают значение общей переменной; два потока с различной частотой считывают и записывают данные в общий буфер памяти.

3. Необходимо обеспечить синхронизированную работу потоков в критической секции с использованием:

  • мьютексов;

  • семафоров;

  • условных переменных.


Синхронизация с помощью мьютекса
В программе имеются 2 функции, записывающие в файл «put.txt» символы «a» и «b».
#include


#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

pthread_mutex_t lock; //запирание мьютекса

ofstream out;

void* one (void* arg){

pthread_mutex_lock(&lock);

for (int i=0;i<5;i++){

out<<"a ";

}

pthread_mutex_unlock(&lock);

return NULL;

}

void* two (void* arg){

pthread_mutex_lock(&lock);

for (int i=0;i<5;i++){

out<<"b ";

}

pthread_mutex_unlock(&lock);

return NULL;

}

int main(){

out.open("put.txt");

pthread_mutex_init(&lock, NULL); //инициализация мьютекса, значение по умолчанию

pthread_t threadA;

pthread_t threadB;

pthread_create(&threadA,NULL,&one,NULL); //создание потока

pthread_create(&threadB,NULL,&two,NULL); //создание потока

pthread_join(threadA,NULL); //блокирование работы потока в ожидании заверш потока

pthread_join(threadB,NULL);

pthread_mutex_destroy(&lock);

out.close();}

Результат

andrey@Andrey4623:~/laba3$ g++ s.cpp -D_REENTERANT -lpthread

andrey@Andrey4623:~/laba3$ ./a.out

andrey@Andrey4623:~/laba3$ ls

a.out put.txt s.cpp

andrey@Andrey4623:~/laba3$ cat put.txt

b b b b b a a a a a

Синхронизация с использованием семафора

В программе 2 потока используя одну и ту же функцию, обращаются к переменной. Первый поток увеличивает её на 1, второй уменьшает на 5.

#include

#include


#include

#include

#include

#include

#include

#include

#include

int count;

sem_t sem;

void* fun(void* arg){

intptr_t s =(intptr_t)arg;

sem_wait(&sem); //ожидание на семафоре

for (int i=1;i<5;i++){

count=count+s;

printf("%i",count);

printf(" ");

}

sem_post(&sem); //увеличение семафора на 1

return NULL;

}

int main(){

sem_init(&sem,0,0); //инициализация семафора

sem_post(&sem); //увеличение семафора на 1

pthread_t thread1,thread2;

pthread_create(&thread1,NULL,&fun,(void*)1);

pthread_create(&thread2,NULL,&fun,(void*)-5);

pthread_join(thread1,NULL);

pthread_join(thread2,NULL);

sem_destroy(&sem);

return 0;}

Результат

andrey@Andrey4623:~/laba3$ g++ s.cpp -D_REENTERANT -lpthread

andrey@Andrey4623:~/laba3$ ls

a.out s.cpp

andrey@Andrey4623:~/laba3$ ./a.out

-5 -10 -15 -20 -19 -18 -17 -16

Синхронизация с помощью условных переменных

В программе 2 потока с функциями обращаются к общей переменной, один из них увеличивает переменную на 1, другой уменьшает на 1.
#include


#include

#include

#include

#include

void* plus(void *arg);

void* min(void *arg);

int z;

pthread_mutex_t mutex;

pthread_cond_t cond; //условная переменная

int main()

{

pthread_mutex_init(&mutex,0);

pthread_cond_init(&cond,0); //инициализация условной переменной

pthread_t plusT;

pthread_create(&plusT,NULL,plus,NULL);

pthread_t minT;

pthread_create(&minT,NULL,min,NULL);

pthread_join(plusT, NULL);

pthread_cancel(minT);

pthread_mutex_destroy(&mutex);

pthread_cond_destroy(&cond);

}

void* plus(void *arg)

{

for (int i = 0; i < 5; i++)

{

pthread_mutex_lock(&mutex);

printf("%i",z);

printf(" ");

z=z+1;

pthread_cond_signal(&cond); //события потоков на усл переменной

pthread_cond_wait(&cond, &mutex); //ожидания события на УП

pthread_mutex_unlock(&mutex);

}

}

void* min(void *arg)

{

while (true)

{

pthread_mutex_lock(&mutex);

printf("%i",z);

printf(" ");

while (z>0) z=z-1;

pthread_cond_signal(&cond);

pthread_cond_wait(&cond, &mutex);

pthread_mutex_unlock(&mutex);

}

}

Результат

andrey@Andrey4623:~/laba3$ g++ s.cpp -D_REENTERANT -lpthread

andrey@Andrey4623:~/laba3$ ls

a.out s.cpp

andrey@Andrey4623:~/laba3$ ./a.out

0 0 1 0 1 0 1 0 1 0 1

4. Убедиться в результативности применения средств синхронизации потоков, сравнив результаты работы программ с использованием и без использования средств синхронизации.
Теперь не будем использовать мьютексы в первой программе

#include


#include

#include

#include

#include

#include

#include

#include

#include

using namespace std;

ofstream out;

void* one (void* arg){

for (int i=0;i<5;i++){

out<<"a ";

}

return NULL;

}

void* two (void* arg){

for (int i=0;i<5;i++){

out<<"b ";

}

return NULL;

}

int main(){

out.open("put.txt");

pthread_t threadA;

pthread_t threadB;

pthread_create(&threadA,NULL,&one,NULL); //создание потока

pthread_create(&threadB,NULL,&two,NULL); //создание потока

pthread_join(threadA,NULL); //блокирование работы потока в ожидании заверш потока

pthread_join(threadB,NULL);

out.close();}

После компиляции

andrey@Andrey4623:~/laba3$ g++ s.cpp -D_REENTERANT -lpthread

andrey@Andrey4623:~/laba3$ ./a.out

andrey@Andrey4623:~/laba3$ cat put.txt

a a a a a b b b b b andrey@Andrey4623:~/laba3$

Вывод
Использование потоков – замечательный инструмент для «распараллеливания» работы программы. Например, если требуется внедрить фоновую проверку правописания в текст, мы можем вынести ее в отдельный поток, и после этого редактирование текста не будет тормозить.



страница 1


скачать

Другие похожие работы: