Yury Kurlykov f6cf3ad3eb | ||
---|---|---|
.. | ||
Makefile | ||
README.md | ||
README_FROM_SRC | ||
main-common.c | ||
main-header.h | ||
mythreads.h | ||
vector-avoid-hold-and-wait.c | ||
vector-deadlock.c | ||
vector-global-order.c | ||
vector-header.h | ||
vector-nolock.c | ||
vector-try-wait.c |
README.md
Лабораторная работа №11
Задание 1
Программа печатает в каждом потоке начальные данные перед vector_add
и результат выполнения данной функции.
Результат может меняться от вызова к вызову, так как весь worker не покрыт мьютексами, но на практике на такой небольшой
программе это маловероятно достижимо.
При добавлении -d
взаимная блокировка возникает не всегда, а только при попадании переключения потоков между мьютексами.
В случае, если число потоков = 1, взаимной блокировки не возникнет.
Задание 2
Программа избегает мёртвой блокировки за счёт упорядочивания по адресам, что позволяет постоянно сохранять порядок блокировки.
В случае если адреса совпадают, то это один мьютекс, и для корректной работы программы его надо блокировать 1 раз.
В случае увеличения числа циклов и потоков, время выполнения растёт.
В случае включения -p
время уменьшается, так как разрешается параллелизм.
Задание 3
Вызовы pthread_mutex_trylock необходимы для создания порядка блокировки, для того чтобы избежать дедлока.
С увеличением числа потоков происходит рост повторных попыток, что является логичным, так как переключение между потоками становится более частым.
Задание 4
Данный подход защищает уязвимое место дедлока, созданием глобального мьютекса, но при этом не даёт различным векторам выполняться параллельно.
При использовании -p
время уменьшается.
Задание 5
Указав memory, мы дожидаемся завершения всех операцией с памятью, что своего рода позволяет заменить мьютексы. (https://ru.wikipedia.org/wiki/GCC_Inline_Assembly)
Сравним время выполнения следующих команд:
./vector-nolock -t -n 2 -l 1000000 -d = 4.08
./vector-nolock -t -n 2 -l 1000000 -d -p = 0.65
./vector-avoid-hold-and-wait -t -n 2 -l 1000000 -d = 2.98
./vector-avoid-hold-and-wait -t -n 2 -l 1000000 -d -p = 0.45
./vector-try-wait -t -n 2 -l 1000000 -d = 1.30
./vector-try-wait -t -n 2 -l 1000000 -d -p = 0.18
./vector-global-order -t -n 2 -l 1000000 -d = 0.69
./vector-global-order -t -n 2 -l 1000000 -d -p = 0.19
Таким образом видно, что vector-nolock работает медленнее других в любом случае.