使用bash脚本创建先来先服务

使用bash脚本创建先来先服务
#/bin/bash
sort(){
    for ((i = 0; i<$n; i++)) 
    do
          
        for((j = 0; j<`expr $n - $i - 1`; j++)) 
        do
          
        if [ ${arrival_time[j]} -gt ${arrival_time[$((j+1))]} ] 
        then
            # swap 
            temp=${arrival_time[j]} 
            arrival_time[$j]=${arrival_time[$((j+1))]}   
            arrival_time[$((j+1))]=$temp 
            temp=${burst_time[j]} 
            burst_time[$j]=${burst_time[$((j+1))]}   
            burst_time[$((j+1))]=$temp
            temp=${pid[j]} 
            pid[$j]=${pid[$((j+1))]}   
            pid[$((j+1))]=$temp
        elif [ ${arrival_time[j]} -eq ${arrival_time[$((j+1))]} ]
        then
            if [ ${pid[j]} -eq ${pid[$((j+1))]} ]
            then
                temp=${arrival_time[j]} 
                arrival_time[$j]=${arrival_time[$((j+1))]}   
                arrival_time[$((j+1))]=$temp 
                temp=${burst_time[j]} 
                burst_time[$j]=${burst_time[$((j+1))]}   
                burst_time[$((j+1))]=$temp
                temp=${pid[j]} 
                pid[$j]=${pid[$((j+1))]}   
                pid[$((j+1))]=$temp
            fi
        fi
        done
    done
}

border(){
    z=121
    for ((i=0; i<$z; i++))
    do
    echo -n "-"
    done
    echo ""
}

findWaitingTime(){
    service_time[0]=0
    waiting_time[0]=0
    for ((i=1; i<$n; i++))
    do
        z=1
        y=`expr $i - $z`
        service_time[$i]=`expr ${service_time[$y]} + ${burst_time[$y]} `
        waiting_time[$i]=`expr ${service_time[$i]} - ${arrival_time[$i]}`
        if [ ${waiting_time[$i]} -lt 0 ]
        then
            waiting_time[$i]=0
        fi
    done
}

findTurnAroundTime(){
    for ((i=0; i<$n; i++))
    do
        tat[$i]=`expr ${waiting_time[$i]} + ${burst_time[$i]}`
    done
}

findAverageTime(){
    sort
    findWaitingTime
    findTurnAroundTime
    total_wt=0
    total_tat=0
    border
    printf "|%-18s|%-20s|%-18s|%-20s|%-18s|%-20s|\n" "Process Id" "Burst time" "Arrival time" "Waiting time" "Turn around time" "Completion time"
    border
    for ((i=0; i<$n; i++))
    do
        total_wt=`expr $total_wt + ${waiting_time[$i]}`
        total_tat=`expr ${tat[$i]} + $total_tat`
        completion_time=`expr ${arrival_time[$i]} + ${tat[$i]}`
        printf "|%-18s|%-20s|%-18s|%-20s|%-18s|%-20s|\n" ${pid[$i]} ${burst_time[$i]} ${arrival_time[$i]} ${waiting_time[$i]} ${tat[$i]} $completion_time
        #echo "${burst_time[$i]}     ${arrival_time[$i]}     ${waiting_time[$i]}       ${tat[$i]}         $completion_time"
    done
    border
    #avgwt=`echo "scale=3; $total_wt / $n" | bc`
    echo -n "Average waiting time ="
    printf %.3f\\n "$(($total_wt / $n))"
    #avgtat=`echo "scale=3; $total_tat / $n" | bc`
    echo -n "Average turn around time ="
    printf %.3f\\n "$(($total_tat / $n))"
    
    for ((i=0; i<8*n+n+1; i++))
    do
        echo -n "-"
        done
        echo ""

    for ((i=0; i<$n; i++))
    do
        echo -n "|   "
        echo -n "P${pid[$i]}"
        echo -n "   "
    done
    echo "|"
    for ((i=0; i<8*n+n+1; i++))
    do
        echo -n "-"
        done
        echo ""
    echo -n "0  "
    for ((i=0; i<$n; i++))
    do
        echo -n "`expr ${arrival_time[$i]} + ${tat[$i]}`"
        echo -n "      "
    done
    echo ""
}


n=$(sed -e '1~2d' fcfs1.txt |awk '{ for (i=1; i<=NF; i++) RtoC[i]= (i in RtoC?RtoC[i] OFS :"") $i; } END{ for (i=1; i<=NF; i++) print RtoC[i] }'| awk '{print $1}' |wc -l)
for ((i=0; i<$n; i++))
do
pid[$i]=$(cat fcfs.txt | awk '{print $1}')
arrival_time[$i]=$(cat fcfs.txt | awk '{print $2}')
burst_time[$i]=$(cat fcfs.txt | awk '{print $3}')
done
findAverageTime

fcfs.txt内容是这样的:

1  15  10
2   17  12

如果输入文件只有一个进程脚本工作正常,如果输入文件中只有一个进程时有多个进程脚本给出错误输出

-------------------------------------------------------------------------------------------------------------------------
|Process Id        |Burst time          |Arrival time      |Waiting time        |Turn around time  |Completion time     |
-------------------------------------------------------------------------------------------------------------------------
|1                 |5                   |10                |0                   |5                 |15                  |
-------------------------------------------------------------------------------------------------------------------------
Average waiting time =0.000
Average turn around time =5.000
----------
|   P1   |
----------
0   15     

答案1

下面是一个使用 perl 可以轻松完成的事情的示例,向您展示为什么应该学习一种更好的语言来处理文本。您的原始 shell 脚本似乎有大约 128 行代码并且不起作用(或者有任何描述它应该如何工作的注释)。这个 Perl 脚本大约有 57 行(不包括大约 30 行注释)。

我试图尽我所能找出每一行的正确计算,但我完全有可能犯了一些错误 - 你的脚本过于复杂(非常如此)并且重复,并且很难理解它在做什么或者为什么要做某事。请随意更正下面的脚本,或者让我知道正确的计算应该是什么。

$ cat summarise_fcfs.pl
#!/usr/bin/perl

use strict;

# Construct the format string for printf. and the ruler line too.
# Width of each field is just enough to fit its header plus a space on
# both sides.

#my @headers = ("Process ID", "Burst time", "Arrival time",
#               "Waiting time", "Turn around time", "Completion time");

# Shorter headers to fit in "standard" 80-column terminal
my @headers = ("Process ID", "Burst", "Arrival", "Waiting", "Turnaround", "Completion");

my $fmt = '|'; my $ruler = '|';
foreach (@headers) {
  my $len = length($_);
  $fmt .= " %${len}s |";
  $ruler .= '-' x ($len + 2) . '|';
};
$fmt .= "\n"; $ruler .= "\n";

my $total_wait = 0;
my $total_tat = 0;

# @data is an Array-of-Arrays (AoA) data structure to hold the values
# for each PID.  Also known as a List-of-Lists or LoL.  See `man
# perllol` and `man perldsc` for details.
my @data = ();

# @st is a single-dimensional array to hold the service time values
# for each PID. These aren't going to be printed with the printf
# format string, so are kept separately from @data (it's easier than
# extracting an array slice from @data to print for each row)
my @st = ();

# Record counter
my $i = 0;

while(<>) {
  chomp;
  s/^\s*|\s*$//g;   # strip leading and trailing whitespace
  s/#.*//;          # strip comments if any
  next if /^\s*$/;  # skip empty lines

  my ($pid, $arrival, $burst) = split;

  my $st = 0;
  if ($i > 0) {
    # previous st + previous burst
    $st = $st[$i-1] + $data[$i-1][1]
  };

  my $wait = $st - $arrival;
  $wait = 0 if ($wait < 0);
  my $tat = $wait + $burst;
  my $completion = $arrival + $tat;

  # Store the data for the current PID in the @data AoA.
  $data[$i] = [ $pid, $burst, $arrival, $wait, $tat, $completion ];

  # and store the service time too
  $st[$i] = $st;

  # keep track of totals and increment the record counter.
  $total_wait += $wait;
  $total_tat += $tat;

  $i++;
};

# All data has been read and processed, now it's time
# to produce some output.
print $ruler, sprintf($fmt, @headers), $ruler;

# sort by arrival time (element 2 of each array in
# @data). Like bash, perl array indices start from zero.
foreach my $row (sort { $data[$a][2] <=> $data[$b][2] } keys @data) {
  printf $fmt, @{ $data[$row] };
};

print $ruler, "\n";

printf "Average waiting time = %.3f\n", $total_wait / $i;
printf "Average turn around time = %.3f\n\n", $total_tat / $i;


# Now print a table of completion times (5th element of @data[$row])
# for each PID.  Limit to 8 columns (PIDs) per output line so it
# doesn't get ridiculously wide.
my $step = 8; # max number of PIDs per output row
for (my $start_col = 0; $start_col < $i ; $start_col += $step) {
  my $end_col = $start_col + $step - 1;
  $end_col = $i-1 if $end_col > $i;

  # Rebuild headers and ruler line for each $step number of PIDs
  my @P_headers = map { "P" . $data[$_][0] } $start_col..$end_col;
  my $P_fmt = '|'; my $P_ruler = '|';

  foreach (@P_headers) {
    #my $len = length($_)+4;
    my $len = 6;  # is 6 characters enough for the PID?
    $P_fmt .= " %${len}s |";
    $P_ruler .= '-' x ($len + 2) . '|';
  };
  $P_fmt .= "\n"; $P_ruler .= "\n";

  # and print the current row
  print $P_ruler, sprintf($P_fmt, @P_headers), $P_ruler;
  printf $P_fmt, map { $data[$_][5] } $start_col..$end_col;
  print $P_ruler, "\n";
}

示例输出:

$ ./summarise_fcfs.pl fcfs.txt 
|------------|-------|---------|---------|------------|------------|
| Process ID | Burst | Arrival | Waiting | Turnaround | Completion |
|------------|-------|---------|---------|------------|------------|
|          1 |    10 |      15 |       0 |         10 |         25 |
|          2 |    12 |      17 |       0 |         12 |         29 |
|------------|-------|---------|---------|------------|------------|

Average waiting time = 0.000
Average turn around time = 11.000

|--------|--------|
|     P1 |     P2 |
|--------|--------|
|     25 |     29 |
|--------|--------|

相关内容