Опубликован: 10.09.2014 | Уровень: для всех | Доступ: платный
Лекция 8:

Потоки

< Лекция 7 || Лекция 8 || Лекция 9 >
Аннотация: Цель: изучить возможности использования потоков в языке NXT-G.

В жизни нам часто приходится делать несколько дел сразу. Например

  • идти и есть мороженое;
  • пить чай, разговаривать и смотреть фотографии;
  • вести мяч, оценивать ситуацию на площадке и придумывать план действий;
  • спускаться по лестнице и разговаривать по телефону.

Для нас это совершенно обычно, и, если разобраться, то окажется, что на самом деле мы умеем производить одновременно гораздо больше действий. Это называется параллельным выполнением задач. Все системы человеческого организма приспособлены к параллельности.

Современные компьютеры широко используют в своей работе технологию многопоточности. При этом программа составляется из нескольких потоков (threads), которые выполняются параллельно. Наш робот тоже умеет выполнять многопоточные программы.

На самом деле мы уже использовали многопоточность неявно: когда запускаются моторы, они начинают работать, а управление немедленно передаётся дальше, на следующий блок программы. Таким образом моторы работают в параллельном режиме. Таким же образом можно запустить блок Sound.

Важно понимать, что параллельность не только придаёт гибкость коду, но и является потенциальным источником ошибок. Большинство из них возникает, когда в двух или более параллельных потоках пытаются одновременно использовать один и тот же ресурс. Например, в первом потоке мы запускаем мотор вперёд, а во втором одновременно пытаемся запустить тот же мотор назад. Или один поток пишет в какую-то переменную некоторые значения, а второй поток одновременно пишет в ту же переменную другие значения. Ещё одна известная проблема возникает при несинхронном запуске или окончании одного из параллельных потоков. Все описанные случаи носят общее название проблемы синхронизации: как организовать совместный доступ из разных потоков к общему ресурсу. При написании программ от нас потребуется известная аккуратность для того, чтобы избежать подобных ситуаций.

Пример 8.1. Двигаемся и разговариваем.

Рассмотрим следующую задачу. Робот должен доехать до чёрной линии и остановиться, сообщив об этом. Во время движения робот должен постоянно произносить какую-либо фразу, например, "Tracking object". Чтобы поведение робота было более "человеческим", сделаем так, что фраза будет произноситься не через равные промежутки времени, а через случайные.

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

Доступ к блоку Timer в меню Sensor

Рис. 8.1. Доступ к блоку Timer в меню Sensor

После его добавления можно произвести настройку:

Из порта № 1 считывается количество миллисекунд, прошедших с момента последнего перезапуска таймера. Поле № 2 (Timer) указывает на номер таймера. Всего в одной программе можно использовать до трёх таймеров. Поле № 3 (Action) показывает действие, которое можно выполнить: считать данные с таймера (Read) или сбросить таймер в ноль (Reset). Другие порты и поля нам пока не понадобятся.

Кроме того, для понимания программы нужно вспомнить правила работы с циклом, выход из которого происходит по логическому условию (см. § 4.5).

Рассмотрим код программы.

Программа к примеру 8.1

увеличить изображение
Рис. 8.2. Программа к примеру 8.1

Возможность создания нового потока мы уже рассматривали в примере 6.2. Чтобы создать новый поток программ, не исходящий из начальной точки, можно установить указатель мыши на нужном участке основной цепочки, нажать клавишу Shift и переместить указатель мыши вверх или вниз. Затем можно размещать новые блоки.

Однако бывает более удобным вначале составить код нового потока, а только затем подвести к нему серую полосу.

Задание 8.1. Внимательно изучите код, прочитайте комментарии. Подумайте, как следует настроить каждый из блоков. Наберите программу, опробуйте её работу. Можно ли было реализовать этот алгоритм в одном потоке? Обоснуйте ответ.

Задание 8.2. Подключите к роботу два датчика касания. Напишите программу, которая в двух потоках (по одному на каждый датчик) подсчитывает и отображает на экране суммарное количество нажатий на кнопки. (Например, если на первую кнопку нажали в сумме 3 раза, а на вторую - 5 раз, то на экране должно быть число 8.) Отображение числа на экране реализуйте в третьем потоке.

Задание 8.3. Измените предыдущую программу так, чтобы на экран выводилась не сумма, а произведение количества нажатий на каждую кнопку. (Например, если на первую кнопку нажали в сумме 3 раза, а на вторую - 4 раза, то на экране должно быть число 12.)

Задание 8.4. Добавьте в предыдущие программы условие останова: при превышении определённого значения (в сумме или произведении) программа должна завершаться.

< Лекция 7 || Лекция 8 || Лекция 9 >
Маргарита Королева
Маргарита Королева
Россия, г. Красноярск
Сергей Конько
Сергей Конько
Россия, Симферополь