Добавил:
github.com Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Скачиваний:
10
Добавлен:
30.09.2023
Размер:
111.43 Кб
Скачать
  1. Упражнения

    1. Подготовка

      1. В соответствии с п. 3.1 из Упражнений первой лабораторной работы подключитесь к командной оболочке Raspberry Pi.

      2. Перейдите в каталог с вашими проектами:

        cd IVT31_Ivanov_Ivan

      3. Создайте директорию для файлов текущей лабораторной работы:

        mkdir lab6_Фамилия

        cd lab6_Фамилия

    2. Работа с многопоточностью

      1. Создайте файл thread.c и скопируйте в него данную программу. В ней происходит создание отдельного потока, который выводит на экран сообщения приветствия и прощания. Для компиляции воспользуйтесь следующим ключом:

gcc thread.c -o thread -lpthread

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void *func(void *args)

{

    printf("Hello from thread!\n");

printf("Goodbye from thread!\n");

}

int main()

{

    pthread_t thread;

    printf("Hello from main!\n");

    pthread_create(&thread, NULL, func, NULL);

    pthread_join(thread, NULL);

    printf("Goodbye from main!\n");

    return 0;

}

      1. Запустите полученную программу. Убедитесь в том, что на экране появились сообщения:

Hello from main!

Hello from thread!

Goodbye from thread!

Goodbye from main!


      1. Исправим программу таким образом, чтобы выводимая потоком строка передавалась в качестве аргумента

gcc thread.c -o thread -lpthread

#include <stdio.h>

#include <stdlib.h>

#include <pthread.h>

void *func(void *args)

{

    printf("%s\n", (char*)args);

}

int main()

{

    pthread_t thread;

    char data[] = "Hello from thread!";

    printf("Hello from main!\n");

    pthread_create(&thread, NULL, func, (void*)data);

    pthread_join(thread, NULL);

    return 0;

}

В результате работы на экране появится сообщение:

Hello from main!

Hello from thread!

      1. Создайте файл data_race.c и скопируйте в него данную программу. Данная программа в двух потоках изменяет значение глобальной переменной Global. Первый поток значение инкрементирует, второй – декрементирует. Для компиляции воспользуйтесь следующим ключом:

gcc data_race.c -o data_race -lpthread

#include <stdio.h>

#include <pthread.h>

#define N 1000000

int Global = 0;

void *Thread1()

{

    for (size_t i = 0; i < N; i++)

        Global++;

}

void *Thread2()

{

    for (size_t i = 0; i < N; i++)

        Global--;

}

int main()

{

    pthread_t t1, t2;

    pthread_create(&t1, NULL, Thread1, NULL);

    pthread_create(&t2, NULL, Thread2, NULL);

    pthread_join(t1, NULL);

    pthread_join(t2, NULL);

    printf("%d\n", Global);

    return 0;

}

      1. Запустим программу несколько раз и убедимся, что значение переменной Global отличается от запуска к запуску из-за гонки данных.

      2. Скорректируем программу таким образом, чтобы исправить ошибку. Для этого добавим в программу мьютекс. Перекомпилируем программу.

gcc data_race.c -o data_race -lpthread

#include <stdio.h>

#include <pthread.h>

#define N 1000000

int Global = 0;

pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;

void *Thread1()

{

    pthread_mutex_lock(&mutex);

    for (size_t i = 0; i < N; i++)

        Global++;

    pthread_mutex_unlock(&mutex);

}

void *Thread2()

{

    pthread_mutex_lock(&mutex);

    for (size_t i = 0; i < N; i++)

        Global--;

    pthread_mutex_unlock(&mutex);

}

int main()

{

    pthread_t t1, t2;

    pthread_create(&t1, NULL, Thread1, NULL);

    pthread_create(&t2, NULL, Thread2, NULL);

    pthread_join(t1, NULL);

    pthread_join(t2, NULL);

    printf("%d\n", Global);

    return 0;

}

      1. Убедитесь, что при многократных запусках программы в результате на экране всегда будет выведен 0.

Соседние файлы в папке OS_labs