mirror of https://github.com/t1meshift/os_labs.git
232 lines
9.5 KiB
Markdown
232 lines
9.5 KiB
Markdown
# Лабораторная работа №9
|
||
|
||
## Задание 2
|
||
|
||
Команда запуска:
|
||
|
||
`valgrind --tool=helgrind ./lab9_main-race_run`
|
||
|
||
Результат:
|
||
|
||
```text
|
||
...
|
||
==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 в двух потоках параллельно.
|
||
|
||
### Решение проблемы:
|
||
|
||
Блокировать незащищенный процесс.
|
||
|
||
Заменить:
|
||
```c
|
||
balance++;
|
||
```
|
||
|
||
на:
|
||
```c
|
||
Pthread_mutex_lock(&m); // блокировка мьютекса
|
||
balance++;
|
||
Pthread_mutex_unlock(&m); // разблокировка
|
||
```
|
||
|
||
|
||
## Задание 3
|
||
|
||
Команда запуска:
|
||
|
||
`valgrind --tool=helgrind ./lab9_main-deadlock_run`
|
||
|
||
Результат:
|
||
|
||
```text
|
||
...
|
||
==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`
|
||
|
||
Результат:
|
||
```text
|
||
...
|
||
==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`
|
||
|
||
Результат:
|
||
|
||
```text
|
||
...
|
||
==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`
|
||
|
||
|
||
|
||
Результат:
|
||
|
||
```text
|
||
...
|
||
==9132== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 7 from 7)
|
||
...
|
||
```
|
||
|
||
helgrind не удалось обнаружить ошибок.
|
||
|
||
По сравнению с прошлой программой данная более эффективна, так как она не производит постоянный опрос,
|
||
а ожидает возвращение cond, и более безопасна для данных.
|