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.