Многопоточное программирование представляет собой подход к созданию программного обеспечения, при котором выполнение одной задачи распределяется на несколько параллельных потоков. Каждый поток работает независимо и может обрабатываться одновременно, что обеспечивает более высокую производительность приложения, особенно на современных многоядерных процессорах. Освоение данной темы играет важную роль в подготовке к ЕГЭ по информатике, так как она формирует умения работать с многозадачностью, организовывать параллельные вычисления и правильно выстраивать синхронизацию процессов.
В рамках данной статьи рассматриваются ключевые теоретические основы многопоточного программирования, раскрываются его базовые механизмы и закономерности. Кроме того, приводится пять практических заданий, выполнение которых позволит глубже освоить материал и эффективно подготовиться к экзаменационным вопросам.
Многопоточное программирование представляет собой метод организации вычислительного процесса, при котором в рамках одной программы создаётся несколько потоков исполнения, способных работать одновременно. Использование потоков обеспечивает рациональное распределение вычислительных ресурсов, что приобретает особое значение в условиях многозадачных операционных систем и при эксплуатации многоядерных процессоров.
Определение потока
Поток можно охарактеризовать как минимальную единицу выполнения программы, управляемую операционной системой. Каждый поток функционирует в собственной области памяти, но при необходимости способен обращаться к общим данным, обеспечивая взаимодействие с другими потоками. В зависимости от архитектуры вычислительной среды потоки могут работать параллельно или переключаться последовательно.
Основные принципы многопоточного программирования
Принципы многопоточного программирования
Работа с многопоточными приложениями строится на ряде фундаментальных положений:
Параллельность. Несколько потоков могут исполняться одновременно на разных ядрах или процессорах, что позволяет существенно повысить скорость обработки данных.
Конкуренция. Разные потоки могут обращаться к одним и тем же ресурсам (например, общей памяти или файлам), из-за чего возникает необходимость учитывать возможные конфликты.
Синхронизация. Для исключения ошибок, вызванных одновременным доступом к общим данным, применяются специальные механизмы: мьютексы, семафоры, барьеры и другие средства координации потоков.
Типы многопоточности
В современной информатике выделяют два ключевых подхода:
Многозадачность (multi-tasking). Подразумевает выполнение нескольких процессов или задач в рамках операционной системы либо одной программы. Как правило, распределение времени процессора осуществляется поочерёдно, за счёт чего создаётся эффект одновременности.
Многопоточность (multi-threading). Более детализированный механизм, при котором одна задача может быть разделена на несколько потоков исполнения. Эти потоки работают параллельно, деля между собой вычислительные ресурсы, что делает выполнение программы более эффективным.
Преимущества:
Повышение производительности: Благодаря параллельному выполнению задач многопоточные программы могут работать быстрее на многоядерных процессорах.
Эффективное использование ресурсов: Потоки позволяют более эффективно использовать ресурсы компьютера, такие как процессорное время.
Недостатки:
Сложность реализации: Многопоточные программы сложны в разработке и отладке, так как они требуют синхронизации данных и предотвращения состояний гонки.
Проблемы с синхронизацией: Несогласованный доступ к общим данным может привести к ошибкам, таким как состояние гонки.
Средства работы с потоками в языках программирования
Реализация многопоточности зависит от конкретного языка программирования, при этом каждая среда предлагает собственные инструменты для создания и управления потоками:
Java. В языке Java для организации параллельных вычислений применяется класс Thread, а также интерфейс Runnable, позволяющий описывать поведение потоков.
Python. В Python поддержка многопоточности обеспечивается модулем threading, предоставляющим удобные механизмы для запуска потоков и их координации.
C++. В стандарте C++ предусмотрены классы std::thread для создания потоков и std::mutex для синхронизации доступа к разделяемым данным.

Упражнение 1: Создание простого потока в Java
Задание: Создайте простой поток в языке Java, который выводит сообщение «Привет из потока» 5 раз.
Решение: Для создания потока в Java можно использовать класс Thread:
public class Main {
public static void main(String[] args) {
Thread thread = new Thread(() -> {
for (int i = 0; i < 5; i++) {
System.out.println(«Привет из потока»);
}
});
thread.start(); // Запуск потока
}
}
Объяснение: В этом примере создается поток, который выполняет анонимную функцию (лямбда-выражение), выводящее сообщение 5 раз.
Упражнение 2: Синхронизация потоков в Python
Задание: Напишите программу на Python, которая создает два потока, каждый из которых увеличивает общий счетчик на 1 тысячу раз. Используйте синхронизацию, чтобы предотвратить ошибку.
Решение:
import threading
# Счётчик
counter = 0
lock = threading.Lock() # Создаём объект Lock для синхронизации
def increment():
global counter
for _ in range(1000):
with lock:
counter += 1 # Обновление счётчика с блокировкой
# Создаем два потока
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(«Итоговый счётчик:», counter)
Объяснение: В этом примере два потока увеличивают общий счетчик. Чтобы избежать ошибок при одновременном доступе к переменной counter, используется механизм блокировки Lock.
Упражнение 3: Многопоточность в C++
Задание: Напишите программу на C++, которая создаёт два потока. Каждый поток должен выполнять функцию, которая выводит числа от 1 до 5.
Решение:
#include <iostream>
#include <thread>
void print_numbers(int start) {
for (int i = start; i < start + 5; i++) {
std::cout << i << std::endl;
}
}
int main() {
std::thread t1(print_numbers, 1);
std::thread t2(print_numbers, 6);
t1.join();
t2.join();
return 0;
}
Объяснение: Программа создаёт два потока. Каждый поток выводит числа от 1 до 5, но потоки могут выполняться параллельно.
Упражнение 4: Проблема синхронизации: состояние гонки
Задание: Напишите программу на Python, которая демонстрирует проблему состояния гонки, если не использовать синхронизацию.
counter = 0
def increment():
global counter
for _ in range(1000):
counter += 1
# Создаём два потока
thread1 = threading.Thread(target=increment)
thread2 = threading.Thread(target=increment)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
print(«Итоговый счётчик:», counter) # Результат может отличаться каждый раз
Объяснение: Без синхронизации два потока могут одновременно обновлять переменную counter, что приведет к некорректному результату.
Упражнение 5: Многозадачность в многопоточном приложении
Задание: Напишите программу, которая запускает два потока, один из которых выводит чётные числа от 1 до 10, а второй – нечётные.
Решение:
import threading
def print_even():
for i in range(2, 11, 2):
print(i)
def print_odd():
for i in range(1, 10, 2):
print(i)
# Создание потоков
thread1 = threading.Thread(target=print_even)
thread2 = threading.Thread(target=print_odd)
thread1.start()
thread2.start()
thread1.join()
thread2.join()
Объяснение: Два потока выполняют вывод чисел: один – чётные, другой – нечётные. Потоки могут выполняться параллельно, ускоряя процесс.
Многопоточное программирование выступает одним из ключевых инструментов разработки высокопроизводительных и ресурсно-эффективных приложений. Понимание принципов организации потоков, механизмов синхронизации и особенностей многозадачной обработки данных является необходимым условием для успешного решения задач, связанных с параллельными вычислениями, в том числе в рамках экзаменационных испытаний по информатике, таких как ЕГЭ. Владение навыками управления потоками и их согласованного взаимодействия позволяет минимизировать ошибки, возникающие при одновременном выполнении операций, и повышает надёжность программных решений.