Sistema Operacional—Simulação e Implementação do Algoritmo do Banqueiro

1: tópico experimental

Simulação e Realização do Algoritmo do Banqueiro

Dois: O propósito do experimento

(1) Saiba mais sobre a execução simultânea de processos.

(2) Fortalecer a compreensão do impasse do processo e compreender os conceitos de estado seguro e estado inseguro.

(3) Domine o uso do algoritmo do banqueiro para evitar problemas de impasse.

3. Projeto geral (incluindo conhecimento prévio ou princípios básicos e algoritmos, ou introdução do módulo, etapas de projeto, etc.)

Conhecimento prévio e justificativa:

1. Execução simultânea de processos: vários processos são executados ao mesmo tempo e compartilham recursos do sistema, o que pode levar à competição por recursos e problemas de impasse.

2. Deadlock: O processo cai em um estado de espera infinita devido à competição por recursos e não pode continuar a ser executado.

3. Estado seguro e estado inseguro: O estado seguro significa que o sistema pode encontrar uma ordem de alocação de recursos, para que todos os processos possam ser concluídos sem problemas, e o estado inseguro significa que tal ordem de alocação não pode ser encontrada.

Princípio do Algoritmo de Banker:

O algoritmo do banqueiro é uma estratégia de alocação de recursos usada para evitar impasses no processo. Ele julga se o sistema está em um estado seguro com base na demanda máxima de recursos e na quantidade de recursos alocados e, se estiver, aloca recursos; se não, espera.

Etapas do projeto:

1. Definir a estrutura de dados dos processos e recursos: É necessário representar informações como a identificação do processo, a demanda máxima, o valor alocado e o valor demandado, bem como o valor total e o valor disponível de recursos.

2. Realize a verificação do status de segurança do algoritmo do banqueiro: percorra todos os processos, simule o processo de alocação de recursos e julgue se o sistema está em um estado seguro.

3. Realize a estratégia de alocação de recursos: aloque recursos de acordo com a demanda máxima e quantidade alocada do processo e atualize o status dos recursos do sistema.

Quatro. Projeto detalhado (incluindo estruturas de dados principais, fluxogramas de programa, códigos-chave, etc.)

Principais estruturas de dados:

Estrutura do processo: contém informações como identificação do processo, demanda máxima, volume alocado e volume de demanda.

Estrutura de recursos: contém a quantidade total e a quantidade disponível de recursos.

*Insira o loop para receber solicitações de recursos do usuário.

* Julgar se o pedido é legal e tentar alocar recursos se for legal.

* Verifique o status de segurança de acordo com o algoritmo do banqueiro para julgar se o sistema está em um status de segurança.

* Se o sistema estiver em um estado seguro, aloque recursos e atualize o estado do sistema.

*Resultados de alocação de saída e status do sistema.

estrutura de dados

número de processos m

Número de classes de recursos m

Vetor de recurso disponível Disponível

Uma matriz contendo m elementos, cada um representando o número de recursos disponíveis para uma classe. Se Disponível[j]=K, significa que existem K recursos do tipo Rj no sistema.

Matriz de demanda máxima Max

Uma matriz n×m, que define a demanda máxima de cada um dos n processos do sistema para m tipos de recursos. Se Max[i,j]=K, significa que o número máximo de recursos do tipo Rj requeridos pelo processo i é K.

Alocação Matriz de Alocação

Uma matriz n×m, que define o número de recursos atualmente alocados para cada processo para cada tipo de recurso no sistema. Se Allocation[i,j]=K, significa que o número de recursos do tipo Rj alocados para o processo i é K.

Matriz de demanda Necessidade

A matriz n×m é usada para representar o número de vários recursos ainda necessários para cada processo. Se Need[i,j]=K, significa que o processo i ainda precisa de K recursos do tipo Rj para completar sua tarefa.

Necessidade[i,j]=Max[i,j]-Alocação[i,j]

Algoritmo de Verificação de Segurança

Configure dois vetores de trabalho

Trabalho registra a quantidade de recursos atualmente disponíveis no sistema, sendo o valor inicial Disponível;

finish registra se todos os processos foram executados, sendo que o valor inicial é um vetor com comprimento n e todos os valores são False.

Encontre um processo do conjunto de processos que satisfaça as seguintes condições,

terminar == Falso;

Necessidade <= Trabalho;

Se encontrado, vá para 3; caso contrário, vá para 4.

Supondo que o processo adquira o recurso, ele pode executar suavemente até que seja concluído, liberando assim o recurso.

Trabalho += Alocação;

Concluir=Verdadeiro;

Executar 2

Se todos os processos terminarem=Verdadeiro, significa seguro; caso contrário, o sistema não é seguro.

*Os usuários podem optar por continuar solicitando recursos ou encerrar o programa.

 

Código chave:

void inicial()

{

    int eu;

    intj;

    printf("Digite o número do processo:\n");

    scanf("%d",&n);

    printf("Digite o número da classe do recurso:\n");

    scanf("%d",&m);    

    printf("Informe o vetor de recurso disponível:\n");

    Disponível = (int*)malloc(sizeof(int)*m);

    for(i=0; i<m; i++)

        scanf("%d",&Disponivel[i]);

    printf("Digite a matriz de demanda máxima:\n");

    Max = (int**)malloc(sizeof(int*)*n);

    for(i=0; i<n; i++)

    {

        Max[i] = (int*)malloc(sizeof(int)*m);

        for(j=0; j<m; j++)

            scanf("%d",&Max[i][j]);

    }

    printf("Digite a matriz de alocação:\n");

    Alocação = (int**)malloc(sizeof(int*)*n);

    for(i=0; i<n; i++)

    {

        Alocação[i] = (int*)malloc(sizeof(int)*m);

        for(j=0; j<m; j++)

            scanf("%d",&Alocação[i][j]);

    }

    Necessidade = (int**)malloc(sizeof(int*)*n);

    for(i=0;i<n;i++)

    {

        Need[i] = (int *)malloc(sizeof(int)*m);

        for(j=0;j<m;j++)

            Necessidade[i][j] = Max[i][j] - Alocação[i][j];

    }

}

solicitação nula()

{

    int i, id;

    new_request = (Pedido*)malloc(sizeof(Pedido));

    new_request->req_src = (int*)malloc(sizeof(int)*m);

    printf("Digite o ID do processo\n");

    scanf("%d",&id);

    new_request->id = id - 1;

    printf("Informe o vetor de recursos do aplicativo de processo\n");

    for(i=0; i<m; i++)

        scanf("%d",&new_request->req_src[i]);

}

processo nulo()

{

    int i = new_request->id;

    if(vector_compare(Need[i],new_request->req_src,m))

        {

            if(vector_compare(Available,new_request->req_src,m))

            {

                vector_sub(Disponível,new_request->req_src,m);

                vector_add(Allocation[i],new_request->req_src,m);

                vector_sub(Need[i],new_request->req_src,m);

                detecção_segura();

            }

            outro

            {

                printf("Os recursos solicitados pelo programa são maiores que os recursos atuais remanescentes do sistema, e a execução será adiada!\n");  

                retornar;

            }

                              

        }

    outro

    {

        printf("Os recursos requisitados pelo programa são maiores que os recursos requeridos pelo programa, e não podem ser executados!\n");

        retornar;

    }    

    se (seguro)

    {

        printf("Segurança do sistema, o processo pode ser executado!\n");

        retornar;

    }

    outro

    {

        printf("O sistema não é seguro, o processo não pode ser executado!\n");

        vector_add(Disponível,new_request->req_src,m);

        vector_sub(Alocação[i],new_request->req_src,m);

        vector_add(Need[i],new_request->req_src,m);

        retornar;

    }

        

}

bool safe_detect()

{

    int *trabalho = Disponível;

    bool *finish = (bool*)malloc(sizeof(bool)*n);

    int eu;

    //Inicializa finaliza

    for(i=0; i<n; i++)

        terminar[i] = Falso;

    

    for(i=0; i<n; i++)

    {

        if(finish[i]==False&&vector_compare(work,Need[i],m))

        {

            printf("Tente executar o processo %d\n", i+1);

            vector_add(work,Allocation[i],m); //Tenta executar o processo e liberar recursos

            terminar[i] = Verdadeiro;

            i = -1; //Após tentar alocar, verifique se ainda existe um processo executável desde o início, considerando i++, então aqui está -1

        }

    }

    

    for(i=0; i<n; i++)

        if(concluir[i]==Falso)

            quebrar;

    se(i==n)

        seguro = Verdadeiro;

    outro

        seguro = Falso;

}

 

Cinco: resultados experimentais e análise

Este código implementa a parte de verificação de segurança do algoritmo do banqueiro. O algoritmo do banqueiro é um algoritmo de alocação e agendamento de recursos usado para evitar que o sistema caia em um estado de impasse. Ele julga se existe uma sequência segura pré-calculando os requisitos máximos de recursos do processo e os recursos atualmente disponíveis, para que todos os processos possam concluir a execução.

A seguir, uma análise da parte de verificação de segurança do código:

1. A função safe_detect() é usada para verificações de segurança. Aceita como entrada o vetor de recursos disponíveis do sistema atual Available, a matriz de demanda máxima do processo Max e a matriz de alocação Alocação.

2. Um trabalho de matriz auxiliar e um acabamento de matriz booleana são criados dentro da função para registrar o vetor de trabalho e o status de conclusão do processo.

3. Inicialize a matriz de acabamento e inicialize o status de conclusão de todos os processos como Falso.

4. A lógica principal para verificação de segurança é uma travessia de loop. Para cada processo i, julgue que seu status de conclusão é Falso e o trabalho de recurso disponível atual é maior ou igual ao vetor de demanda Need[i] do processo i. Se as condições forem atendidas, significa que o processo i pode ser executado, ou seja, tentar executar o processo e liberar os recursos correspondentes.

5. Depois de tentar executar o processo i, defina o status de conclusão do processo i como True e aumente o trabalho do vetor de recursos disponível pela quantidade de recursos alocados para o processo i.

6. Volte ao início e continue a procurar o próximo processo que satisfaça a condição até que nenhum processo que atenda à condição seja encontrado ou todos os processos sejam marcados como concluídos.

Por fim, verifique se todos os processos estão marcados como concluídos. Nesse caso, o sistema é considerado seguro e a variável safe é definida como True; caso contrário, safe é definida como False.

Em experimentos, você pode testar simulando diferentes situações de processo e recurso. De acordo com a solicitação de recursos do processo de entrada, o sistema alocará recursos de acordo com o algoritmo do banqueiro e exibirá o resultado da alocação e o status do sistema. Você pode observar se o sistema está em um estado seguro, bem como a alocação de recursos.

6. Resumo e experiência

Por meio desse experimento, compreendi ainda mais a execução simultânea de processos e problemas de impasse e aprendi o princípio e a implementação do algoritmo do banqueiro. Realize o algoritmo do banqueiro por meio de codificação real, o que aprofunda a compreensão do algoritmo e melhora a capacidade de programação. Ao mesmo tempo, através do processo de experimentação, tenho uma compreensão mais profunda do conceito de competição de recursos e status de segurança e tenho uma ideia clara de como evitar problemas de impasse. Ao analisar os resultados experimentais, posso avaliar melhor a segurança do sistema e a eficácia da estratégia de alocação de recursos, o que fornece uma experiência útil para o projeto e desenvolvimento do sistema real.

Acho que você gosta

Origin blog.csdn.net/CSH__/article/details/131382772
Recomendado
Clasificación