При работе с большими скриптами в Linux нередко требуется запускать задачи в фоновом режиме. Но чтобы всё работало корректно, нужно уметь управлять очередями задач. Сейчас разберемся, как организовать очередь фоновых задач с использованием функций и переменных, чтобы избежать перегрузки системы.
🛠 Что нужно знать о фоновых задачах?
В Bash можно запускать процессы в фоне, добавляя & в конце команды. Но если одновременно запущено слишком много процессов, система может потерять стабильность. Управление очередью фоновых задач позволяет:
Ограничить количество одновременно выполняемых задач.
Следить за состоянием задач.
Организовать приоритет выполнения.
Реализация очереди задач
1. Пример базового скрипта с ограничением задач. Этот скрипт запускает фоновые задачи, ограничивая их количество:
#!/bin/bash
# Максимальное количество фоновых задач
MAX_JOBS=4
# Функция для ожидания завершения задач
wait_for_jobs() {
while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
sleep 1
done
}
# Функция, которая будет выполняться в фоне
task() {
local id=$1
echo "Task $id started"
sleep $((RANDOM % 5 + 1)) # Имитация выполнения
echo "Task $id completed"
}
# Основной цикл
for i in {1..10}; do
wait_for_jobs # Ожидание освобождения очереди
task "$i" & # Запуск задачи в фоне
done
# Ожидание завершения всех задач
wait
echo "All tasks completed!"
Вывод:
Task 1 started
Task 2 started
Task 3 started
Task 4 started
Task 1 completed
Task 5 started
Task 2 completed
Task 6 started
...
All tasks completed!
При выполнении скрипта можно увидеть, что одновременно запускается не более четырёх задач:
2. Улучшение с приоритетами и динамическим управлением
Добавление приоритетов. Мы можем использовать массивы для хранения задач с разным приоритетом.
#!/bin/bash
MAX_JOBS=3
PRIORITY_TASKS=("High1" "High2")
NORMAL_TASKS=("Normal1" "Normal2" "Normal3")
wait_for_jobs() {
while (( $(jobs -r | wc -l) >= MAX_JOBS )); do
sleep 1
done
}
task() {
local name=$1
echo "Task $name started"
sleep $((RANDOM % 5 + 2))
echo "Task $name completed"
}
# Выполнение задач с приоритетом
for task_name in "${PRIORITY_TASKS[@]}" "${NORMAL_TASKS[@]}"; do
wait_for_jobs
task "$task_name" &
done
wait
echo "All prioritized tasks completed!"
Задачи с приоритетом выполняются в первую очередь, вывод:
Task High1 started
Task High2 started
Task Normal1 started
Task High1 completed
Task Normal2 started
...
All prioritized tasks completed!
3. Дополнительные трюки: управление через переменные
Динамическое добавление задач в очередь. Очередь можно заполнять динамически, используя массив:
#!/bin/bash
MAX_JOBS=4
TASK_QUEUE=()
# Функция добавления задач в очередь
add_task() {
TASK_QUEUE+=("$1")
}
# Функция выполнения задач из очереди
process_queue() {
for task_name in "${TASK_QUEUE[@]}"; do
wait_for_jobs
task "$task_name" &
done
}
# Добавляем задачи в очередь
add_task "Task1"
add_task "Task2"
add_task "Task3"
add_task "Task4"
add_task "Task5"
# Обрабатываем очередь
process_queue
wait
echo "Dynamic queue processing completed!"
✅ Преимущества такого подхода:
Контроль над нагрузкой на систему.
Возможность задания приоритетов выполнения.
Легкость добавления задач в реальном времени.
Масштабируемость для больших скриптов.
BashTex 📱 #bash #utils