Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методические материалы СПтаОС (3курс).doc
Скачиваний:
0
Добавлен:
01.07.2025
Размер:
929.79 Кб
Скачать

Результаты выполнения программы, 1-й вариант

Consumer считывает -1

Producer записывает 1

Consumer считывает 1

Consumer считывает 1

Consumer считывает 1

Consumer сумма прочитанных значений: 2

Завершение потока Consumer.

Producer записывает 2

Producer записывает 3

Producer записывает 4

Producer заканчивает генерирование.

Завершение потока Producer.

Результаты выполнения программы, 2-й вариант

Producer записывает 1

Producer записывает 2

Consumer считывает 2

Producer записывает 3

Consumer считывает 3

Producer записывает 4

Producer заканчивает генерирование.

Завершение потока Producer.

Consumer считывает 4

Consumer считывает 4

Consumer сумма прочитанных значений: 13

Завершение потока Consumer.

Результаты выполнения программы, 3-й вариант

Producer записывает 1

Consumer считывает 1

Producer записывает 2

Consumer считывает 2

Producer записывает 3

Consumer считывает 3

Producer записывает 4

Consumer считывает 4

Producer заканчивает генерирование.

Завершение потока Producer.

Consumer сумма прочитанных значений: 10

Завершение потока Consumer.

Вспомним, что по условию примера поток Producer должен генерировать значения до того, как поток Consumer захочет их прочесть, и что каждое значение должно быть прочитано потоком Consumer только один раз. Тем не менее, изучив выводимые на экран результаты 1-го варианта выполнения программы, мы увидим, что Потребитель извлекает из буфера -1, прежде чем Производитель успеет записать в буфер новое значение. В то же врема, первое значение (1) Потребитель прочтет три раза. Более того, Потребитель закончит свое выполнение до того, как Производитель сгенерирует значения 2, 3и 4, в результате чего все эти три значения будут потеряны. Соответственно, общая сумма (2) также не будет отвечать ожидаемому результату.

Во втором варианте поток потерял значение 1, поскольку значения 1 и 2 были сгенерированы, прежде чем поток Потребителя смог начать чтение 1. Кроме того, значение 4 было прочитано дважды. В последнем варианте показано, что при определенной доле везения можно получить правильный результат.

Данный пример доказывает, что доступ к разделяемым объектам со стороны параллельных потоков должен контролироваться весьма тщательно, иначе программа начнет выдавать некорректные результаты. О том, как можно решить данную проблему вы узнаете в дальнейшем, изучая взаимоисключающий монопольный доступ.

Вопросы для самопроверки

  1. (Да/Нет). Правда ли, что в данном примере Производитель-Потребитель непротиворечивости и постоянства выходного результата можно достичь, если удалить из программного кода вызов функции sleep?

  2. Какое самое маленькое и самое бльшое значение может принимать переменная sum в данном примере, и при каких условиях этого можно добиться?

Ответы

  1. Нет. Вызов функции sleep всего лишь подчеркивает тот факт, что порядок и время выполнения тех или иных команд в системе определить невозможно. Кроме того, мы не можем предсказать скорость выполнения этих потоков, поэтому результаты могут оказаться некорректными.

  2. Наименьшее значение (-4) переменная sum примет в том случае, если Потребитель выполнит все четыре итерации чтения из буфера, прежде чем Производитель успеет записать хотя бы одно значение. Самое большое значение (16) будет получено в том случае, если Производитель сгенерирует все четыре значения до того, как Потребитель успеет прочитать хотя бы одно из них.