Загрузка данных
Вот полный план от начала до конца. Просто копируй команды по очереди в терминал.
**ЧАСТЬ 1. Подготовка папки**
```
mkdir -p ~/lab5_threads
cd ~/lab5_threads
```
**ЧАСТЬ 2. Проверка что есть gcc и gdb**
```
which gcc
which gdb
```
Если что-то не найдено, ставим:
```
sudo apt update
sudo apt install gcc gdb build-essential
```
**ЧАСТЬ 3. Задание 1 — bash скрипт monitor_system.sh**
Создаем файл:
```
nano monitor_system.sh
```
Вставляем туда этот код:
```
#!/bin/bash
echo "Системный монитор"
monitor_processes() {
while true; do
clear
echo "Системный монитор"
echo "Время: $(date '+%Y-%m-%d %H:%M:%S')"
echo
echo "--- Топ-5 процессов по CPU ---"
ps aux --sort=-%cpu | head -6
echo
echo "--- Топ-5 процессов по RAM ---"
ps aux --sort=-%mem | head -6
echo
echo "Всего процессов: $(ps -e | wc -l)"
sleep 2
done
}
monitor_processes &
MONITOR_PID=$!
echo "PID фонового процесса: $MONITOR_PID"
echo "Нажмите Ctrl+C для остановки"
trap 'kill $MONITOR_PID > /dev/null 2>&1; echo "Мониторинг остановлен"; exit 0' SIGINT
wait $MONITOR_PID
```
Сохраняем: Ctrl+O, Enter, Ctrl+X.
Делаем исполняемым и запускаем:
```
chmod +x monitor_system.sh
./monitor_system.sh
```
Смотришь как обновляется экран каждые 2 секунды. Жмешь Ctrl+C. Должно написать "Мониторинг остановлен".
**ЧАСТЬ 4. Задание 2 — C программа с потоками**
Создаем файл:
```
nano thread_demo.c
```
Вставляем код:
```
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <unistd.h>
#include <sys/syscall.h>
#define NUM_THREADS 3
#define NUM_ITERATIONS 5
typedef struct {
int thread_id;
} thread_data_t;
void* worker_thread(void* arg) {
thread_data_t* data = (thread_data_t*)arg;
pid_t tid = syscall(SYS_gettid);
printf("Поток %d запущен. PID: %d, TID: %ld\n",
data->thread_id, getpid(), (long)tid);
for (int i = 0; i < NUM_ITERATIONS; i++) {
printf("Поток %d: шаг %d\n", data->thread_id, i);
sleep(1);
}
printf("Поток %d завершен\n", data->thread_id);
pthread_exit(NULL);
}
int main() {
printf("=== Демонстрация работы потоков ===\n");
printf("Основной процесс PID: %d\n", getpid());
pthread_t threads[NUM_THREADS];
thread_data_t thread_data[NUM_THREADS];
for (int i = 0; i < NUM_THREADS; i++) {
thread_data[i].thread_id = i;
int result = pthread_create(&threads[i], NULL, worker_thread, &thread_data[i]);
if (result != 0) {
fprintf(stderr, "Ошибка создания потока %d: %d\n", i, result);
exit(EXIT_FAILURE);
}
}
for (int i = 0; i < NUM_THREADS; i++) {
pthread_join(threads[i], NULL);
}
printf("Все потоки завершены\n");
return 0;
}
```
Сохраняем: Ctrl+O, Enter, Ctrl+X.
**ЧАСТЬ 5. Компиляция и обычный запуск**
```
gcc -pthread -o thread_demo thread_demo.c
chmod +x thread_demo
./thread_demo
```
Смотришь как 3 потока работают по 5 шагов.
**ЧАСТЬ 6. Запуск в фоне**
```
./thread_demo > output.txt 2>&1 &
cat output.txt
ps -eLf | grep thread_demo
```
**ЧАСТЬ 7. Наблюдение через ps**
```
./thread_demo &
PID=$!
ps -L -p $PID
kill $PID
```
**ЧАСТЬ 8. Наблюдение через top**
```
./thread_demo &
top -H -p $(pgrep thread_demo)
```
Выходишь из top клавишей q.
**ЧАСТЬ 9. Отладка в gdb**
Компилируем с отладкой:
```
gcc -g -pthread -o thread_demo_debug thread_demo.c
```
Запускаем gdb:
```
gdb ./thread_demo_debug
```
Внутри gdb по очереди вводишь:
```
break main
run
info threads
thread 2
break worker_thread
continue
next
quit
```
**ВСЁ.** Лабораторная выполнена полностью.