Boa tarde a todos. O programa, cujo código segue abaixo, é um escalonador de processos(que está sendo estudado na disiplina de Sistemas Operacionais, da faculdade), que processa em ordem de prioridade (do maior para o menor - decrescente). O intervalo de tempo disponível para processar cada processo é digitado pelo usuário, assim como o tempo total de cada execução.
A cada execução, o programa deve executar os processos de maior prioridade, obedecendo os intervalos e o tempo de processamento total. A cada intervalo de processamento, deve ser permitido ao usuário cadastrar novos processos e esses serão reorgranizados de acordo com a prioridade e executado, seguindo os padrões acima, infinitamente.
Um exemplo.
sendo P, um processo. Pri, prioridade. T, Tempo. ID, identificação
P(Pri, T, ID)
Os seguintes processos devem ser processados num tempo total de 10, a cada intervalo de tempo 2, para cada processamento
P(7, 4, A)
P(9, 7, B)
Execução:
P(9, 2, B)
P(9, 4, B)
P(9, 6, B)
P(9, 7, B)
P(7, 2, A)
P(7, 3, A)
Perceba que aqui termina, pois o tempo já é igual a 10, mas faltou executar somente o tempo 1 do processo A
Neste momento, o ucuário entra com um novo processo:
P(8, 3, C)
Então na próxima execução devemos ter:
P(8, 2, C)
P(8, 3, C)
P(7, 1, A)
Agora não há mais processos pendentes, então deve perguntar ao usuário se deseja cadastrar mais, em caso negativo, encerra o programa.
No entanto, para permitir que o usuário cadastre novos processos, estou utilizando a estrutura:
struct EProcesso{ int prioridade; //Prioridade do Processo int tempo; //Tempo de Execução do Processo int id; //Id do Processo };//struct EProcesso struct Processos{ int tam; //Quantidade de processos int intervalo; //Intervalo de tempo entre a execução de cada processo int tempo; //Tempo total de execução do processo struct EProcesso * elem; //Cadastro dos processos };//struct Processos //variáveis globais struct Processos processo; [/codebox]
E quando o usuário solicita o cadastramento de um novo processo entre um processamento e outro, utilizao o comando
"free(processo.elem)" para liberar memória e peço para alocar memória em processo.elem, novamente.
O curioso é que na primeira vez em que processo, este código funciona, por exemplo, este exemplo acima citado roda perfeitamente, no entanto se for cadastrar mais um processo, ocorre erro de violação de memória no comando "free(processo.elem)
O compilador é o Borland 5.02
Sei que o problema é um pouco complicado, mas já analisei diversas vezes o código, e não parece haver erro de lógico, estou suspeitando que seja algum erro de sintaxe, já que não tenho muita experiência com o C. Desde já agradeço a atenção.
//estruturas struct EProcesso{ int prioridade; //Prioridade do Processo int tempo; //Tempo de Execução do Processo int id; //Id do Processo };//struct EProcesso
struct Processos{ int tam; //Quantidade de processos int intervalo; //Intervalo de tempo entre a execução de cada processo int tempo; //Tempo total de execução do processo struct EProcesso * elem; //Cadastro dos processos };//struct Processos
//variáveis globais struct Processos processo;
//funções int getnum(void); // função retorna inteiro struct EProcesso * alocaprocesso(int n); // função alocar vetor de processos void preenche_processo(void); // preenche cada processo(prioridade e tempo) void Imprime_Processos(void); // impressão para teste void Ordena_Processos(void); // ordena processos por ordem de prioridade void Executa_Escalonador(void); // Executa o escalonador(imprime o processamento e registra na struct int Conta_Processos(void); // Conta Processos ainda ativos void Limpa_Processos(void); // Mantém os processos ainda ativos nas primeiras posições da lista void Inicial(void); // Escalonador
//códigos-fonte dos módulos int getnum(){ int n; scanf("%d", &n); return n; }//int getnum
struct EProcesso * alocaprocesso(int n){ struct EProcesso * vetor; vetor = (struct EProcesso *) malloc(sizeof(struct EProcesso)*n); //alocar memória if (!vetor){ printf("Não foi possível alocar Memória"); return 0; }// if return vetor; //retorna o vetor }//int alocaprocesso
void preenche_processo(int n){ int i; processo.elem = alocaprocesso(n); //preenche cada processo for (i=0; i<n; i++){ printf("##-- Processo %d --##\n", i+1); printf("Prioridade: "); processo.elem[i].prioridade = getnum(); printf("Tempo: "); processo.elem[i].tempo = getnum(); processo.elem[i].id = i+1; }//for }//void preenche_processos
void Imprime_Processos(void){ //****impressão para teste int i; for (i=0; i<processo.tam; i++){ printf("%d \n", i+1); printf("Prioridade: %d \n", processo.elem[i].prioridade); printf("Tempo: %d \n", processo.elem[i].tempo); printf("ID: %d \n", processo.elem[i].id); } }//void Imprime_Processos
void Ordena_Processos(void){ struct EProcesso aux; int i, j; for (i=0; i < processo.tam; i++) for (j=i+1; j < processo.tam; j++){ if (processo.elem[i].prioridade < processo.elem[j].prioridade) { aux = processo.elem[i]; processo.elem[i] = processo.elem[j]; processo.elem[j] = aux; };//if };//for }//void Ordena_Processos
void Executa_Escalonador(void){
int i; //auxiliar int tempo_total; //armazena tempo total subtraindo a cada processamento int ultimo_tempo; //armazena ultimo tempo impresso struct EProcesso aux;
tempo_total = processo.tempo; printf("#### EXECUCAO ##### \n"); printf("| Prioridade | Tempo | ID | \n"); //Imprime Cabeçalho for (i=0; i < processo.tam; i++){ //roda por todos os processos ultimo_tempo = 0; aux = processo.elem[i]; //faz aux receber o processo em execução while ((aux.tempo > 0) && (tempo_total>0)){ //repete até utilizar todo o tempo do processo e tempo de processamento não ter esgotado if (!(tempo_total < aux.tempo)){ //Tempo total de processamento for maior ou igual que o tempo do processo if (aux.tempo < processo.intervalo){//Tempo restante do processo, menor que o tempo do intervalo
ultimo_tempo = ultimo_tempo + aux.tempo; tempo_total = tempo_total - aux.tempo; printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo aux.tempo=0; }//if else{ //Tempo do intervalo menor ou igual ao tempo do processo
ultimo_tempo = ultimo_tempo + processo.intervalo; tempo_total = tempo_total - processo.intervalo; printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo aux.tempo = aux.tempo - processo.intervalo; };//else }//if else{ //Tempo restante do processamento é menor que o tempo do processo if (!(tempo_total > processo.intervalo)){//se tempo total do processamento for menor ou igual ao intervalo ultimo_tempo = ultimo_tempo + tempo_total; aux.tempo = aux.tempo - tempo_total; tempo_total = 0; printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo }//if else{//Tempo total do processamento é maior que o intervalo ultimo_tempo = ultimo_tempo + processo.intervalo; tempo_total = tempo_total - processo.intervalo; aux.tempo = aux.tempo - processo.intervalo; printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo };//else };//else };//while processo.elem[i].tempo = aux.tempo; };//for }//void Executa_Escalonador
int Conta_Processos(void){ int qde_processos; //armazena qde de processos conforme processamento int i; //auxiliar qde_processos=0; for (i=0; i < processo.tam; i++){ if (processo.elem[i].tempo) qde_processos = qde_processos ++ ; };//for return qde_processos; }//void Conta_processos
void Limpa_Processos(void){ int i, j; for (i=0; i<processo.tam; i++){ if (!(processo.elem[i].tempo)){ for (j=i; j<processo.tam; j++){ if (j != processo.tam-1){ processo.elem[j] = processo.elem[j+1]; };//if };//for };//if };//for }//void Limpa_Processos
void Inicial(void){ int opcao; int qde, i; struct EProcesso * aux; printf ("Tempo do intervalo de cada processamento = "); processo.intervalo = getnum(); printf ("Tempo total do processamento = "); processo.tempo = getnum(); printf ("Quantidade de processos a serem cadastrados = "); processo.tam = getnum(); preenche_processo(processo.tam); Ordena_Processos(); do{ Executa_Escalonador(); printf("Pressione qualquer tecla. \n"); getch(); qde = Conta_Processos(); //retorna nº de processos a serem processados if (qde){ printf("Ainda resta(m) %d Processo(s) a ser(em) processado(s), deseja cadastrar mais?\n", qde); }//if else{ printf("Não há mais processos a serem processados, deseja cadastrar novos?\n"); };//else printf("1 - Sim \n"); printf("0 - não \n"); printf("Opção: "); opcao = getnum(); if (opcao){ //Cadastramento de novo(s) processo(s) Limpa_Processos(); //faz os processos ainda ativos serem os primeiros da lista if (qde){ aux = alocaprocesso(qde); //prepara aux para receber os atuais processos ainda ativos for (i=0; i<qde; i++){ //armazena os processos ativos em aux aux[i]=processo.elem[i]; };//for };//if printf("Informe a quantidade de novos processos a serem cadastrados: "); processo.tam = qde + getnum(); free(processo.elem); processo.elem = alocaprocesso(processo.tam); preenche_processo((processo.tam - qde)); //preenche somente os novos processos. if (qde){ for (i=qde; i<processo.tam; i++){ processo.elem[i] = aux[(i-qde)]; //Preenche os processos em aux };//for free(aux); };//if Ordena_Processos(); };//if
Pergunta
Guest Fabio Lopes
Boa tarde a todos. O programa, cujo código segue abaixo, é um escalonador de processos(que está sendo estudado na disiplina de Sistemas Operacionais, da faculdade), que processa em ordem de prioridade (do maior para o menor - decrescente). O intervalo de tempo disponível para processar cada processo é digitado pelo usuário, assim como o tempo total de cada execução.
A cada execução, o programa deve executar os processos de maior prioridade, obedecendo os intervalos e o tempo de processamento total. A cada intervalo de processamento, deve ser permitido ao usuário cadastrar novos processos e esses serão reorgranizados de acordo com a prioridade e executado, seguindo os padrões acima, infinitamente.
Um exemplo.
sendo P, um processo. Pri, prioridade. T, Tempo. ID, identificação
P(Pri, T, ID)
Os seguintes processos devem ser processados num tempo total de 10, a cada intervalo de tempo 2, para cada processamento
P(7, 4, A)
P(9, 7, B)
Execução:
P(9, 2, B)
P(9, 4, B)
P(9, 6, B)
P(9, 7, B)
P(7, 2, A)
P(7, 3, A)
Perceba que aqui termina, pois o tempo já é igual a 10, mas faltou executar somente o tempo 1 do processo A
Neste momento, o ucuário entra com um novo processo:
P(8, 3, C)
Então na próxima execução devemos ter:
P(8, 2, C)
P(8, 3, C)
P(7, 1, A)
Agora não há mais processos pendentes, então deve perguntar ao usuário se deseja cadastrar mais, em caso negativo, encerra o programa.
No entanto, para permitir que o usuário cadastre novos processos, estou utilizando a estrutura:
E quando o usuário solicita o cadastramento de um novo processo entre um processamento e outro, utilizao o comando
"free(processo.elem)" para liberar memória e peço para alocar memória em processo.elem, novamente.
O curioso é que na primeira vez em que processo, este código funciona, por exemplo, este exemplo acima citado roda perfeitamente, no entanto se for cadastrar mais um processo, ocorre erro de violação de memória no comando "free(processo.elem)
O compilador é o Borland 5.02
Sei que o problema é um pouco complicado, mas já analisei diversas vezes o código, e não parece haver erro de lógico, estou suspeitando que seja algum erro de sintaxe, já que não tenho muita experiência com o C. Desde já agradeço a atenção.
Meu e-mail é: fabiomirand@globo.com
#include <conio.h>
#include <stdlib.h>
//estruturas
struct EProcesso{
int prioridade; //Prioridade do Processo
int tempo; //Tempo de Execução do Processo
int id; //Id do Processo
};//struct EProcesso
struct Processos{
int tam; //Quantidade de processos
int intervalo; //Intervalo de tempo entre a execução de cada processo
int tempo; //Tempo total de execução do processo
struct EProcesso * elem; //Cadastro dos processos
};//struct Processos
//variáveis globais
struct Processos processo;
//funções
int getnum(void); // função retorna inteiro
struct EProcesso * alocaprocesso(int n); // função alocar vetor de processos
void preenche_processo(void); // preenche cada processo(prioridade e tempo)
void Imprime_Processos(void); // impressão para teste
void Ordena_Processos(void); // ordena processos por ordem de prioridade
void Executa_Escalonador(void); // Executa o escalonador(imprime o processamento e registra na struct
int Conta_Processos(void); // Conta Processos ainda ativos
void Limpa_Processos(void); // Mantém os processos ainda ativos nas primeiras posições da lista
void Inicial(void); // Escalonador
//códigos-fonte dos módulos
int getnum(){
int n;
scanf("%d", &n);
return n;
}//int getnum
struct EProcesso * alocaprocesso(int n){
struct EProcesso * vetor;
vetor = (struct EProcesso *) malloc(sizeof(struct EProcesso)*n); //alocar memória
if (!vetor){
printf("Não foi possível alocar Memória");
return 0;
}// if
return vetor; //retorna o vetor
}//int alocaprocesso
void preenche_processo(int n){
int i;
processo.elem = alocaprocesso(n);
//preenche cada processo
for (i=0; i<n; i++){
printf("##-- Processo %d --##\n", i+1);
printf("Prioridade: ");
processo.elem[i].prioridade = getnum();
printf("Tempo: ");
processo.elem[i].tempo = getnum();
processo.elem[i].id = i+1;
}//for
}//void preenche_processos
void Imprime_Processos(void){ //****impressão para teste
int i;
for (i=0; i<processo.tam; i++){
printf("%d \n", i+1);
printf("Prioridade: %d \n", processo.elem[i].prioridade);
printf("Tempo: %d \n", processo.elem[i].tempo);
printf("ID: %d \n", processo.elem[i].id);
}
}//void Imprime_Processos
void Ordena_Processos(void){
struct EProcesso aux;
int i, j;
for (i=0; i < processo.tam; i++)
for (j=i+1; j < processo.tam; j++){
if (processo.elem[i].prioridade < processo.elem[j].prioridade) {
aux = processo.elem[i];
processo.elem[i] = processo.elem[j];
processo.elem[j] = aux;
};//if
};//for
}//void Ordena_Processos
void Executa_Escalonador(void){
int i; //auxiliar
int tempo_total; //armazena tempo total subtraindo a cada processamento
int ultimo_tempo; //armazena ultimo tempo impresso
struct EProcesso aux;
tempo_total = processo.tempo;
printf("#### EXECUCAO ##### \n");
printf("| Prioridade | Tempo | ID | \n"); //Imprime Cabeçalho
for (i=0; i < processo.tam; i++){ //roda por todos os processos
ultimo_tempo = 0;
aux = processo.elem[i]; //faz aux receber o processo em execução
while ((aux.tempo > 0) && (tempo_total>0)){ //repete até utilizar todo o tempo do processo e tempo de processamento não ter esgotado
if (!(tempo_total < aux.tempo)){ //Tempo total de processamento for maior ou igual que o tempo do processo
if (aux.tempo < processo.intervalo){//Tempo restante do processo, menor que o tempo do intervalo
ultimo_tempo = ultimo_tempo + aux.tempo;
tempo_total = tempo_total - aux.tempo;
printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo
aux.tempo=0;
}//if
else{ //Tempo do intervalo menor ou igual ao tempo do processo
ultimo_tempo = ultimo_tempo + processo.intervalo;
tempo_total = tempo_total - processo.intervalo;
printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo
aux.tempo = aux.tempo - processo.intervalo;
};//else
}//if
else{ //Tempo restante do processamento é menor que o tempo do processo
if (!(tempo_total > processo.intervalo)){//se tempo total do processamento for menor ou igual ao intervalo
ultimo_tempo = ultimo_tempo + tempo_total;
aux.tempo = aux.tempo - tempo_total;
tempo_total = 0;
printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo
}//if
else{//Tempo total do processamento é maior que o intervalo
ultimo_tempo = ultimo_tempo + processo.intervalo;
tempo_total = tempo_total - processo.intervalo;
aux.tempo = aux.tempo - processo.intervalo;
printf("| %d | %d | %d | \n", aux.prioridade, ultimo_tempo, aux.id); //imprime processo
};//else
};//else
};//while
processo.elem[i].tempo = aux.tempo;
};//for
}//void Executa_Escalonador
int Conta_Processos(void){
int qde_processos; //armazena qde de processos conforme processamento
int i; //auxiliar
qde_processos=0;
for (i=0; i < processo.tam; i++){
if (processo.elem[i].tempo)
qde_processos = qde_processos ++ ;
};//for
return qde_processos;
}//void Conta_processos
void Limpa_Processos(void){
int i, j;
for (i=0; i<processo.tam; i++){
if (!(processo.elem[i].tempo)){
for (j=i; j<processo.tam; j++){
if (j != processo.tam-1){
processo.elem[j] = processo.elem[j+1];
};//if
};//for
};//if
};//for
}//void Limpa_Processos
void Inicial(void){
int opcao;
int qde, i;
struct EProcesso * aux;
printf ("Tempo do intervalo de cada processamento = ");
processo.intervalo = getnum();
printf ("Tempo total do processamento = ");
processo.tempo = getnum();
printf ("Quantidade de processos a serem cadastrados = ");
processo.tam = getnum();
preenche_processo(processo.tam);
Ordena_Processos();
do{
Executa_Escalonador();
printf("Pressione qualquer tecla. \n");
getch();
qde = Conta_Processos(); //retorna nº de processos a serem processados
if (qde){
printf("Ainda resta(m) %d Processo(s) a ser(em) processado(s), deseja cadastrar mais?\n", qde);
}//if
else{
printf("Não há mais processos a serem processados, deseja cadastrar novos?\n");
};//else
printf("1 - Sim \n");
printf("0 - não \n");
printf("Opção: ");
opcao = getnum();
if (opcao){ //Cadastramento de novo(s) processo(s)
Limpa_Processos(); //faz os processos ainda ativos serem os primeiros da lista
if (qde){
aux = alocaprocesso(qde); //prepara aux para receber os atuais processos ainda ativos
for (i=0; i<qde; i++){ //armazena os processos ativos em aux
aux[i]=processo.elem[i];
};//for
};//if
printf("Informe a quantidade de novos processos a serem cadastrados: ");
processo.tam = qde + getnum();
free(processo.elem);
processo.elem = alocaprocesso(processo.tam);
preenche_processo((processo.tam - qde)); //preenche somente os novos processos.
if (qde){
for (i=qde; i<processo.tam; i++){
processo.elem[i] = aux[(i-qde)]; //Preenche os processos em aux
};//for
free(aux);
};//if
Ordena_Processos();
};//if
// Imprime_Processos();
// getch();
} while (qde);
}//void inicial
//######---FIM---######
main(){
Inicial();
}//main
Link para o comentário
Compartilhar em outros sites
5 respostass a esta questão
Posts Recomendados
Participe da discussão
Você pode postar agora e se registrar depois. Se você já tem uma conta, acesse agora para postar com sua conta.