Обрезать уровень дерева двоичных процессов по уровням, начиная с листьев - PullRequest
0 голосов
/ 22 сентября 2019

Мне нужно создать bash-скрипт, который запускает программу на C, которая порождает двоичное дерево процессов n-глубины, используя fork(), а затем уравновешивает его уровень за уровнем, начиная с листьев дерева и заканчивая корнем.

Код C, который составляет дерево процессов, довольно прост. Вы можете увидеть полный код здесь , но версия TL; DR выглядит следующим образом:

void tree(int n):
   if (n==0) exit
   rchild=fork()
   if (parent)
      lchild=fork()
      if (left child)
         tree(n-1)
   else //right child
      tree(n-1)
sleep(1000)

глядя на вывод pstree -pn PID Я заметил, что идентификаторы PID детей были последовательными,поэтому я решил убить процесс числовым значением на основе PID первого экземпляра.Но, возможно, из-за того, что команды, принимающие значения PID, или другие системные процессы, выполнение кода внутри сценария сбивает значения PID, поэтому мой подход больше не работает.Я пытаюсь получить PID напрямую, используя вывод pstree, но сейчас кажется, что это будет беспорядок sed и awk вызовов только для получения одного уровня PID.

Вот скрипт bash, который у меня есть:

#!/bin/bash

if [ ! -f "./fork.run" ]
then
    >&2 echo 'Error: binary mising'
    >&2 echo 'Generate it with "gcc -o fork.run fork.c"'
    exit
fi

if [ "$1" == "" ]
then
    >&2 echo "Error: you need to indicate the depth of the tree"
    exit
fi

./fork.run $(( $1 - 1 )) &
fork=$! #store tree's PID
n=$1

echo "fork started with PID $fork"


while [ $n -gt 1 ]
do

    echo "Tree of the process $fork:"
    pstree -pn $fork

    sleep 1

    #calculation based on properties of the binary tree
    min=$(( 2 ** (n - 1) + $fork ))
    max=$(( (2 ** n) - 1 + $fork ))

    echo "starting trim: level $n"


    for i in `seq $min $max`
    do
        echo "killing $i"
        kill $i #I also tried kill -9 $i, but it's the same.
    done

    sleep 1

    echo "processes from $min to $max trimmed"

    let n--
done

pstree -pn $fork

sleep 1

echo "starting trim: level $n (final)"

kill $fork

sleep 1

echo "initial process ($fork) trimmed"

1 Ответ

0 голосов
/ 25 сентября 2019

Похоже, что это будут беспорядочные вызовы sed и awk только для того, чтобы получить один уровень PID.

Ну, это не так уж и беспорядочно с awk.Следующая замена вашего цикла while обрабатывает вывод pstree сценарием awk, который определяет (на основе позиции в каждой строке) уровни дерева, к которым относятся содержащиеся процессы, и убивает уровни на выбранныхуровень n.

while [ $n -gt 1 ]
do
    echo "Tree of the process $fork:"
    pstree -p $fork
    sleep 1
    echo "starting trim: level $n"
    pstree -pl $fork |
    gawk -vn=$n '
    /^[^ ]/ { level = 1; start[1] = 1 }             # line starting with non-space has top level
    /^ /    { level = trats[match($0, "[|`]-")] }   # determine first level of line from position of |- or `-
    {   while (i = match(substr($0, start[level]), ")-[-+]-"))
        { start[level+1] = start[level]+i+1; ++level; trats[start[level]] = level } # hash level by position
        if (match(substr($0, start[n]), "^.-[^(]+.([0-9]+)", p)) { print "killing "p[1]; system("kill "p[1]) }
    }   '
    sleep 1
    echo "processes trimmed"
    let n--
done
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...