RECURA | Программирование & IT
Практические советы, утилиты и обучающие материалы для разработчиков, DevOps-инженеров и системных администраторов. Всё о разработке, Linux и информационной безопасности. Реклама: @tarabuk1n РКН: clck.ru/3RnyGw Биржа: https://telega.in/c/recura_tech
Show more📈 Analytical overview of Telegram channel RECURA | Программирование & IT
Channel RECURA | Программирование & IT (@recura_tech) in the Russian language segment is an active participant. Currently, the community unites 14 621 subscribers, ranking 8 544 in the Technologies & Applications category and 44 701 in the Russia region.
📊 Audience metrics and dynamics
Since its creation on невідомо, the project has demonstrated rapid growth, gathering an audience of 14 621 subscribers.
According to the latest data from 06 September, 2026, the channel demonstrates stable activity. Although there has been a change in the number of participants by 542 over the last 30 days and by -5 over the last 24 hours, overall reach remains high.
- Verification status: Not verified
- Engagement rate (ER): The average audience engagement rate is 14.45%. Within the first 24 hours after publication, content typically collects 9.35% reactions from the total number of subscribers.
- Post reach: On average, each post receives 2 113 views. Within the first day, a publication typically gains 1 367 views.
- Reactions and interaction: The audience actively supports content: the average number of reactions per post is 13.
- Thematic interests: Content is focused on key topics such as linux, docker, devops, утилит, kubernetes.
📝 Description and content policy
The author describes the resource as a platform for expressing subjective opinions:
“Практические советы, утилиты и обучающие материалы для разработчиков, DevOps-инженеров и системных администраторов. Всё о разработке, Linux и информационной безопасности.
Реклама: @tarabuk1n
РКН: clck.ru/3RnyGw
Биржа: https://telega.in/c/recura_te...”
Thanks to the high frequency of updates (latest data received on 07 September, 2026), the channel maintains relevance and a high level of publication reach. Analytics show that the audience actively interacts with content, making it an important point of influence in the Technologies & Applications category.
for ... & wait можно построить небольшой диспетчер: запускать ограниченное число процессов, сразу подхватывать освободившийся слот и запускать следующую задачу. Это особенно удобно для массовой обработки файлов, хостов и независимых команд.
📝 Динамически заполняем пул
wait -n ждёт не конкретный PID, а любой завершившийся процесс. Поэтому неважно, какая задача закончилась первой — как только слот освобождается, можно запускать следующую. Здесь одновременно работают максимум четыре задачи, а очередь не привязана к порядку их завершения.
pids=()
for host in server-{01..20}; do
while ((${#pids[@]} >= 4)); do
wait -n "${pids[@]}"
pids=($(jobs -rp))
done
ssh "$host" "hostname && uptime" &
pids+=("$!")
done
wait
📝 Узнаём, какая именно задача завершилась
В Bash 5.1+ wait -p позволяет получить идентификатор завершившегося задания. Это уже позволяет связывать результат процесса с конкретной задачей. Теперь завершение процесса можно сразу сопоставить с исходным файлом, сервером или другим объектом обработки.
declare -A task
for file in *.log; do
process "$file" &
task[$!]="$file"
done
while ((${#task[@]})); do
wait -n -p pid "${!task[@]}"
status=$?
printf '%s: exit=%d\n' "${task[$pid]}" "$status"
unset "task[$pid]"
done
📝 Превращаем это в полноценную очередь
Самый интересный вариант — вообще не создавать все процессы сразу. Храним задачи в массиве и запускаем следующую только после освобождения рабочего слота.
tasks=(server-{01..50})
declare -A running
limit=5
while ((${#tasks[@]} || ${#running[@]})); do
while ((${#tasks[@]} && ${#running[@]} < limit)); do
host="${tasks[0]}"
tasks=("${tasks[@]:1}")
ssh "$host" "deploy.sh" &
running[$!]="$host"
done
if ((${#running[@]})); then
wait -n -p pid "${!running[@]}"
rc=$?
printf '[%s] exit=%d\n' "${running[$pid]}" "$rc"
unset "running[$pid]"
fi
done
❗️ Так Bash превращается в простой планировщик: одновременно выполняется фиксированное число задач, а новые автоматически запускаются по мере освобождения ресурсов.
tags: #bash #автоматизация #полезно
🧭 @recura_tech 🌐 VK 🌐 MAX🌟 VPS/VDS серверы с мгновенной активацией. Современные процессоры, NVMe-накопители, защита от DDoS.Почему выбирают нас❓ ⚡️ Мгновенная активация Запуск виртуального сервера всего за 58 секунд после оплаты. ☄️ Стабильность Гарантированное время бесперебойной работы 99,98%. ⚙️ Полный контроль Доступ к полному управлению сервером и выбор любой операционной системы. 💸 Выгодные тарифы Стоимость от 500 рублей в месяц. 🌐 Локации на выбор: Россия, Нидерланды, Германия. ⚡️ Высокая скорость: Современные процессоры, скоростные твердотельные накопители и канал связи 1 гигабит в секунду. 🔒 Безопасность Надежная встроенная защита от распределенных атак. 🕯 Гибкость Возможность масштабирования ресурсов и удобный программный интерфейс для автоматизации. 🖥 Программа приглашений Получите по 250₽ на внутренний баланс хостинга, пригласив своего друга и оплатив сервер. 🚨 Акция: бонус 100% на пополнение! 🎁 Пополните баланс от 2000 рублей и получите еще 2000 рублей на внутренний кошелек для оплаты услуг. Регистрируйтесь на сайте, выбирайте любой тариф и запустите проект уже сегодня! ➡️ Сайт: anwhale.cloud ⛓ Бот: @anwhalecloud_bot ⛓ Канал: @anwhalecloud
rsync, ssh, kubectl, terraform, docker. Проблема начинается, когда одна команда зависает или одновременно запускается слишком много процессов. asyncio позволяет управлять десятками внешних команд, ограничивать параллельность и автоматически завершать зависшие операции.
📝 Параллельный запуск команд с таймаутом
import asyncio
async def run(cmd, sem):
async with sem:
proc = await asyncio.create_subprocess_exec(
*cmd, stdout=asyncio.subprocess.PIPE,
stderr=asyncio.subprocess.PIPE
)
try:
out, err = await asyncio.wait_for(
proc.communicate(), timeout=30
)
except asyncio.TimeoutError:
proc.kill()
await proc.wait()
raise
return proc.returncode, out, err
async def main():
sem = asyncio.Semaphore(5)
jobs = [
["ssh", host, "uptime"]
for host in ["server1", "server2", "server3"]
]
results = await asyncio.gather(
*(run(job, sem) for job in jobs)
)
for code, out, err in results:
print(code, out.decode().strip())
asyncio.run(main())
📌 Как это работает:
• Semaphore(5) ограничивает количество одновременно работающих процессов, поэтому автоматизация не создаёт неконтролируемую нагрузку на систему или сеть.
• wait_for() устанавливает таймаут для каждой команды. Если внешний процесс зависает, Python принудительно завершает его и освобождает воркер.
• asyncio.gather() позволяет собрать результаты множества операций в одной точке, что удобно для массового выполнения команд на серверах.
❗️ Такой подход превращает Python-скрипт в небольшой оркестратор: можно параллельно выполнять ssh, kubectl, docker или любые другие CLI-команды, сохраняя контроль над количеством процессов и временем выполнения каждой операции.
tags: #python #автоматизация #разработка
🧭 @recura_tech 🌐 VK 🌐 MAX— Бэкенд, архитектурные решения и разбор факапов — DevOps, инфраструктура и CI/CD — Безопасность, системный анализ и QA — Тимлидство, архитектура процессов и управление командами👉🏻 Добавить папку в Telegram в один клик
/dev-устройствами или специализированным железом, часто используют privileged: true. Это даёт контейнеру слишком широкие права, хотя приложению обычно нужен только конкретный ресурс. В Kubernetes можно описать устройство точечно через Device Plugin и получить его в Pod как обычный ресурс.
📝 Запрашиваем только нужный GPU
Kubernetes передаст контейнеру один GPU, а планировщик не позволит разместить Pod на узле, где такой ресурс недоступен.
apiVersion: v1
kind: Pod
metadata:
name: inference
spec:
containers:
- name: app
image: my-inference:latest
resources:
limits:
nvidia.com/gpu: 1
📝 Выделяем специализированное устройство через Device Plugin
Device Plugin регистрирует устройство в kubelet, после чего Kubernetes учитывает его при планировании Pod. Такой механизм работает не только для GPU, но и для FPGA, сетевых ускорителей и другого специализированного оборудования.
resources:
limits:
example.com/fpga: 1
env:
- name: DEVICE_MODE
value: "accelerated"
📝 Проверяем распределение устройств
В описании узла можно увидеть доступные и занятые ресурсы, а в Pod — какие ограничения и запросы были назначены.
kubectl describe node worker-01
kubectl get pods \
-o wide
kubectl describe pod inference
❗️ Device Plugin позволяет уйти от универсального privileged и описывать аппаратные ресурсы как часть декларативной модели Kubernetes. Для инфраструктуры с GPU и специализированными устройствами это заметно безопаснее и лучше масштабируется, чем ручная передача /dev/* в контейнер.
tags: #devops #безопасность #k8s
🧭 @recura_tech 🌐 VK 🌐 MAXpidfd решает эту проблему: ядро выдаёт файловый дескриптор, привязанный именно к конкретному процессу.
📝 Получение pidfd и безопасная отправка сигнала
Вместо обычного kill(pid, SIGTERM) сигнал отправляется через дескриптор конкретного процесса. Даже если исходный PID уже был переиспользован, pidfd не переключится на новый процесс.
#define _GNU_SOURCE
#include <sys/syscall.h>
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
int main(void)
{
pid_t pid = 12345;
int pidfd = syscall(SYS_pidfd_open, pid, 0);
if (pidfd == -1) {
perror("pidfd_open");
return 1;
}
if (syscall(SYS_pidfd_send_signal,
pidfd, SIGTERM, NULL, 0) == -1) {
perror("pidfd_send_signal");
return 1;
}
close(pidfd);
}
📝 Ожидание завершения процесса через poll
pidfd можно использовать как обычный файловый дескриптор: ждать завершения процесса через poll или epoll, объединяя управление процессами с обычным событийным циклом.
#include <poll.h>
#include <stdio.h>
#include <unistd.h>
int wait_process(int pidfd)
{
struct pollfd pfd = {
.fd = pidfd,
.events = POLLIN
};
int rc = poll(&pfd, 1, 10000);
if (rc == 0) {
printf("timeout\n");
return 1;
}
if (pfd.revents & POLLIN)
printf("process exited\n");
return 0;
}
📝 Получение pidfd напрямую при создании процесса
В реальных системах удобнее использовать clone3() с CLONE_PIDFD: ядро сразу возвращает pidfd для нового процесса. Это особенно интересно для собственных рантаймов, менеджеров процессов и систем автоматизации, где жизненный цикл дочерних процессов контролируется программно.
#define _GNU_SOURCE
#include <sys/wait.h>
#include <unistd.h>
#include <stdio.h>
int main(void)
{
int pidfd;
pid_t pid = clone(
NULL, NULL, 0, NULL
);
printf("pid=%d\n", pid);
return 0;
}
❗️ pidfd — современный механизм Linux, который устраняет целый класс ошибок, связанных с переиспользованием PID. Для разработчиков системных сервисов это особенно полезно при создании воркеров, супервизоров и собственных менеджеров процессов, где надёжное управление жизненным циклом важнее привычного kill().
tags: #linux #разработка #полезно
🧭 @recura_tech 🌐 VK 🌐 MAX