Bash Unix Shellscript中最短作业优先(SJF)和循环(RR)调度以及甘特图的问题

时间:2019-05-23 07:01:47

标签: bash unix

我想使用Unix Shellscript模拟CPU调度算法,但是执行Shell脚本时代码不起作用。大部分代码是从C转换而来的,由于C的结构与bash有所不同,因此我不知道如何解决该代码。这是代码:

sjf()
{
  #Variables and arrays
    declare -a processesSJF=("${!1}")
    declare -a arrivalsSJF=("${!2}")
    declare -a burstsSJF=("${!3}")
    numberOfProcesses="${#processesSJF[@]}" #declare how many processes are there
    next=1 #Fix for sorting via burst. This stores the index.
    #Sorted already by arrival time. Now, it is time to sort via burst/execution. Arrival time <= Execution time
    for ((i=0; i<$numberOfProcesses; i++))
    do
        totalBurstTime=$(($totalBurstTime + ${burstsSJF[i]}))
        minimumBurst=${burstsSJF[$next]} #variable redirection again to the value of next

        for ((j=next; j<$numberOfProcesses; j++))
        do
              if (($totalBurstTime >= ${arrivalsSJF[j]} && ${burstsSJF[j]} < $minimumBurst))
              then
                  tempProcess=${processesSJF[$next]}
                  ${processesSJF[$next]}=${processesSJF[j]}
                  ${processesSJF[j]}=$tempProcess
                  tempArrival=${arrivalsSJF[$next]}
                  ${arrivalsSJF[$next]}=${arrivalsSJF[j]}
                  ${arrivalsSJF[j]}=$tempArrival
                  tempBurst=${burstsSJF[$next]}
                  ${burstsSJF[$next]}=${burstsSJF[j]}
                  ${burstsSJF[j]}=$tempBurst
              fi
        done
        next=$(($next+=1))
    done

  #Ordering done. Now it is ordered, I can call on FCFS' calcs.
  #The completion time for all processes
    for ((i=0; i<$numberOfProcesses; i++)) #for loop from https://www.cyberciti.biz/faq/bash-for-loop/
    do
        sumOfBurstTimeSJF=$(($sumOfBurstTimeSJF + ${burstsSJF[i]})) #Adds bursts up to that point.
        completion_timeSJF[i]=$sumOfBurstTimeSJF #Defines completion time for that process,
    done

  #Turnaround time and waiting time
    for ((i=0; i<$numberOfProcesses; i++))
    do
        turnaround_timeSJF[i]=$((${completion_timeSJF[i]} - ${arrivalsSJF[i]}))
        total_turnaroundSJF=$(($total_turnaroundSJF + ${turnaround_timeSJF[i]}))

        waiting_timeSJF[i]=$((${turnaround_timeSJF[i]} - ${burstsSJF[i]}))
        total_waitSJF=$(($total_waitSJF + ${waiting_timeSJF[i]}))
    done

  #To-do: Ordering and gantt chart

  #Printing of table
  #printf doc:https://www.computerhope.com/unix/uprintf.htm
    printf "Program Name\t Arrival Time\t Burst Time\t Completion Time\t Turnaround Time\t Waiting Time\t\n\n"
    for ((i=0; i<$numberOfProcesses; i++))
    do
        printf " %s\t\t\t %s\t %s\t %s\t %s\t %s\t\n\n" "${processesSJF[i]}" "${arrivalsSJF[i]}" "${burstsSJF[i]}" "${completion_timeSJF[i]}" "${turnaround_timeSJF[i]}" "${waiting_timeSJF[i]}"

    done
    printf "Average waiting time: %s\n" "$(($total_waitSJF / $numberOfProcesses))"
    printf "Average turnaround time: %s\n" "$(($total_turnaroundSJF / $numberOfProcesses))"

}

round_robin()
{
    #Variables and arrays 
    declare -a processesRR=("${!1}") 
    declare -a arrivalsRR=("${!2}")
    declare -a burstsRR=("${!3}")
    time_quantum="${!4}" #Redirection again needed so $4 won't just print out tquantum
    numberOfProcesses="${#processesRR[@]}" #declare how many processes are there
    numberOfProcessesRunning=$numberOfProcesses #for keeping track on which processes have finished.

    #Time remaining assignment
    for ((i=0; i<$numberOfProcesses; i++))
    do
        remaining_time[i]=${burstsRR[i]}
    done

    printf "Program Name\t Arrival Time\t Burst Time\t Completion Time\t Turnaround Time\t Waiting Time\t\n\n"
    #Actual algorithm. This also generates the table.
    complete=0 #For checking the completion of a process
    time=0 #For checking time
    i=0 #Index
    resetPrinciple=$(($numberOfProcesses - 1)) #Fix to test operation not allowing arithmetic
    while [[ $numberOfProcessesRunning != 0 ]]
    do
        if (( ${remaining_time[i]} <= $time_quantum && ${remaining_time[i]} > 0 )) #indicates process completes here.
        then
            ((time += ${remaining_time[i]}))
            remaining_time[i]=0
            complete=1

            elif (( ${remaining_time[i]} > 0 )) #process was not completed
            then
                ((${remaining_time[i]} - $time_quantum))
                ((time += ${remaining_time[i]}))
        fi

        if (( ${remaining_time[i]} == 0 && $complete == 1 ))
        then
            numberOfProcessesRunning=$(($numberOfProcessesRunning - 1))
            completion_timeRR[i]=$time
            turnaround_timeRR[i]=$(($time - ${arrivalsRR[i]}))
            waiting_timeRR[i]=$((${turnaround_timeRR[i]} - ${burstsRR[i]}))
            total_turnaroundRR=$(($total_turnaroundRR + ${turnaround_timeRR[i]}))
            total_waitingRR=$(($total_waitingRR + ${waiting_timeRR[i]}))
            complete=0 #start again anew
            printf " %s\t %s\t %s\t %s\t %s\t %s\t\n\n" "${processesRR[i]}" "${arrivalsRR[i]}" "${burstsRR[i]}" "${completion_timeRR[i]}" "${turnaround_timeRR[i]}" "${waiting_timeRR[i]}"
        fi

        if (( $i == $resetPrinciple )) #to avoid non-existent entries and let it reset
        then
            i=0
            elif (( ${arrivalsRR[i]} <= $time )) #check time if we can increment
            then
                ((i++))
        else #¯\_(ツ)_/¯
            i=0
        fi
    done
    avrWaitTime=$(($total_waitingRR / $numberOfProcesses))
    avrTurnTime=$(($total_turnaroundRR / $numberOfProcesses))
    printf "Average waiting time: %s\n" "$avrWaitTime"
    printf "Average turnaround time: %s\n" "$avrTurnTime"

}
# based on http://blockofcodes.blogspot.com/2015/08/first-come-first-serve-scheduling.html
    # print Gantt chart
    printf "\n" # Empty line
    printf "          GANTT CHART          \n"
    printf "          ***********          \n"


    # print top bar
    printf "\n"
    for((i=0; i<$numberOfProcesses; i++))
        do
            for((j=0; j<"${burstsFCFS[i]}"; j++)) 
                do
                    printf -- "--" #this fixes the argument error - Gabs
                    printf ""
                done
        done
    printf "\n|"

    # printing process id in the middle
    for((i=0; i<$numberOfProcesses; i++))

        do
            for((j=0; j<${burstsFCFS[i]} - 1; j++)) 
            do
                #printf "\n"
                printf ${processesFCFS[i]}
            done
            for((j=0; j<${burstsFCFS[i]} - 1; j++)) 
            do
                printf " "
                printf "|"
            done
        done

    printf "\n "
    # printing bottom bar
    for((i=0; i<$numberOfProcesses; i++))

        do
            for((j=0; j<${burstsFCFS[i]} - 1; j++)) 
                do
                    printf -- "--"
                    printf ""
                done
        done

    printf "\n"

    # printing the time line
    printf "0"
    for((i=0; i<$numberOfProcesses; i++))

        do
        turnaround_time[i]=$((${completion_time[i]} - ${arrivalsFCFS[i]}))
        for((j=0; j<${burstsFCFS[i]}; j++)) 

            do
                printf " "
            if [[ ${turnaround_time[i]} > ${turnaround_time[$((j + 1))]} ]] 

                then 
                printf "\b" # backspace : remove 1 space
                printf "%d " "${turnaround_time[i]}"
            fi
            done
        done


    printf "\n"

甘特图的输出如下所示:

      GANTT CHART          
      ***********          
  

-------------------------------------------------- -------------------
  | Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1Proc1 | | | | | | | | | | | | | | | | | | | | | | | | ProcessProcessProcessProcess | | | | P2P2 | |
   -------------------------------------------------- ----------
  0 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 25 30 30 30 32 32

0 个答案:

没有答案