9.5 KiB
Лабораторная работа №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, и более безопасна для данных.