os_labs/lab9/README.md

9.5 KiB
Raw Blame History

Лабораторная работа №9

Задание 2

Команда запуска:

valgrind --tool=helgrind ./lab9_main-race_run

Результат:

...
==4862== Possible data race during read of size 4 at 0x30A014 by thread #1
==4862== Locks held: none
==4862==    at 0x108D27: main (main-race.c:15)
==4862==
==4862== This conflicts with a previous write of size 4 by thread #2
==4862== Locks held: none
==4862==    at 0x108CDF: worker (main-race.c:8)
==4862==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==4862==    by 0x4E496DA: start_thread (pthread_create.c:463)
==4862==    by 0x518288E: clone (clone.S:95)
==4862==  Address 0x30a014 is 0 bytes inside data symbol "balance"
...

helgrind сообщает, что возможно использование переменной balance в двух потоках параллельно.

Решение проблемы:

Блокировать незащищенный процесс.

Заменить:

balance++;

на:

Pthread_mutex_lock(&m); // блокировка мьютекса
balance++;
Pthread_mutex_unlock(&m); // разблокировка

Задание 3

Команда запуска:

valgrind --tool=helgrind ./lab9_main-deadlock_run

Результат:

...
==6272== Thread #3: lock order "0x30A040 before 0x30A080" violated
==6272==
==6272== Observed (incorrect) order is: acquisition of lock at 0x30A080
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108D06: worker (main-deadlock.c:13)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==
==6272==  followed by a later acquisition of lock at 0x30A040
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108D12: worker (main-deadlock.c:14)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==
==6272== Required order was established by acquisition of lock at 0x30A040
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108CEC: worker (main-deadlock.c:10)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==
==6272==  followed by a later acquisition of lock at 0x30A080
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108CF8: worker (main-deadlock.c:11)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==
==6272==  Lock at 0x30A040 was first observed
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108CEC: worker (main-deadlock.c:10)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==  Address 0x30a040 is 0 bytes inside data symbol "m1"
==6272==
==6272==  Lock at 0x30A080 was first observed
==6272==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==6272==    by 0x108CF8: worker (main-deadlock.c:11)
==6272==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==6272==    by 0x4E496DA: start_thread (pthread_create.c:463)
==6272==    by 0x518288E: clone (clone.S:95)
==6272==  Address 0x30a080 is 0 bytes inside data symbol "m2"
...

helgrind сообщает, что блокировка мьютексов происходит в неправильном порядке.

Задание 4

Команда запуска:

valgrind --tool=helgrind ./lab9_main-deadlock-global_run

Результат:

...
==7133== Thread #3: lock order "0x30A080 before 0x30A0C0" violated
==7133==
==7133== Observed (incorrect) order is: acquisition of lock at 0x30A0C0
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108D12: worker (main-deadlock-global.c:15)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==
==7133==  followed by a later acquisition of lock at 0x30A080
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108D1E: worker (main-deadlock-global.c:16)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==
==7133== Required order was established by acquisition of lock at 0x30A080
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108CF8: worker (main-deadlock-global.c:12)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==
==7133==  followed by a later acquisition of lock at 0x30A0C0
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108D04: worker (main-deadlock-global.c:13)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==
==7133==  Lock at 0x30A080 was first observed
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108CF8: worker (main-deadlock-global.c:12)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==  Address 0x30a080 is 0 bytes inside data symbol "m1"
==7133==
==7133==  Lock at 0x30A0C0 was first observed
==7133==    at 0x4C3403C: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x108AD7: Pthread_mutex_lock (mythreads.h:23)
==7133==    by 0x108D04: worker (main-deadlock-global.c:13)
==7133==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7133==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7133==    by 0x518288E: clone (clone.S:95)
==7133==  Address 0x30a0c0 is 0 bytes inside data symbol "m2"
...

helgrind сообщает об аналогичной ошибке 3 заданию, тогда как она отсутствует, так как дополнительный мьютекс не допускает такую ситуацию.

Задание 5

Команда запуска:

valgrind --tool=helgrind ./lab9_main-signal_run

Результат:

...
==7499== Possible data race during write of size 4 at 0x30A014 by thread #2
==7499== Locks held: none
==7499==    at 0x108D36: worker (main-signal.c:9)
==7499==    by 0x4C36C26: ??? (in /usr/lib/valgrind/vgpreload_helgrind-amd64-linux.so)
==7499==    by 0x4E496DA: start_thread (pthread_create.c:463)
==7499==    by 0x518288E: clone (clone.S:95)
==7499==
==7499== This conflicts with a previous read of size 4 by thread #1
==7499== Locks held: none
==7499==    at 0x108D83: main (main-signal.c:16)
==7499==  Address 0x30a014 is 0 bytes inside data symbol "done"
...

helgrind сообщает о возможном одновременном использовании переменной done.

Такой метод ожидания потока не является эффективным, так как:

  • может наступить чтение в момент записи
  • требует дополнительных затрат ожидающего потока.

Наиболее эффективно было бы использовать мьютексы.

Задание 6

Команда запуска:

valgrind --tool=helgrind ./lab9_main-signal-cv_run

Результат:

...
==9132== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 7 from 7)
...

helgrind не удалось обнаружить ошибок.

По сравнению с прошлой программой данная более эффективна, так как она не производит постоянный опрос, а ожидает возвращение cond, и более безопасна для данных.