Design do curso do sistema operacional com base em C# Winform: Simulação de tecnologia de entrada e saída com spool.
É necessário projetar um processo de saída de spool e dois processos de usuário que solicitam saída, bem como um programa de serviço de saída de spool. Quando o processo do usuário que solicita a saída deseja gerar uma série de informações, o programa de serviço de saída é chamado e o programa de serviço de saída envia as informações para o poço de saída. Quando um sinalizador final de saída é encontrado, indica que a saída do arquivo de saída do processo é concluída. Depois disso, um bloco de solicitação de saída é aplicado (usado para gravar o nome do processo do usuário solicitando saída, a posição das informações no poço de saída, a duração das informações a serem emitidas etc.) e aguarde a saída do processo de spool.
Quando o processo de saída de spool está funcionando, ele será lançado na impressora ou monitor com base nas informações a serem emitidas por cada processo registrado no bloco de solicitação. Aqui, o processo de saída do SP00ling e o processo do usuário que solicitam a saída podem ser executados simultaneamente.
A programação de processos usa um algoritmo aleatório, que é consistente com a aleatoriedade das informações de saída do processo. A probabilidade de agendamento dos dois processos do usuário que solicita a saída é de 45% cada, e o processo de saída de spool é de 10%, o que é determinado pela simulação do número aleatório gerado pelo gerador de números aleatórios.
Existem três estados básicos do processo, ou seja, executável, esperando e final. O estado executável é o estado em que o processo está em execução ou aguardando a programação; O estado de espera é dividido no estado de espera 1, no estado de espera 2 e no estado de espera 3.
As condições para a mudança de estado são:
① Quando o processo é executado, ele é definido para o estado "final".
② Quando o programa de serviço envia bem as informações de saída para a saída, se descobrir que o poço de saída está cheio, o processo de chamada será definido como "Waiting State 1".
③ Quando o processo de spool é emitido, se a saída estiver vazia, ele entrará no "estado de espera 2".
④ Depois que o processo de spool produzir um bloco de informações, ele deve liberar imediatamente o espaço de saída de saída ocupado pelo bloco de informações e definir o processo aguardando a saída para o "estado executável".
⑤ Depois que o programa de serviço produzir informações para a saída bem e formar um bloco de informações de solicitação de saída, se o processo de spool estiver em um estado de espera, ele será definido para o "estado executável".
⑥ Quando o processo do usuário solicita o bloco de saída, se não houver um bloco de solicitação disponível, o processo de chamada entra no "estado de espera 3".
Existem dois processos de usuário solicitando saída no sistema, e os dois processos são nomeados Processos do Usuário A e Processo do Usuário B, respectivamente. O usuário pode precisar produzir mais de um arquivo e os arquivos são separados por um sinalizador final de saída. O sinalizador final de saída do arquivo usado neste experimento é #.
O usuário precisa inserir todo o conteúdo do arquivo a ser emitido durante a fase de inicialização e salvá -lo em uma matriz. Quando o processo do usuário estiver agendado, se as três condições seguintes forem atendidas: ainda existe um arquivo que não é emitido, o espaço restante no poço de saída pode abaixar o arquivo e há um bloco de solicitação de saída disponível, o arquivo é enviado para a saída bem e, em seguida, a saída de saída é solicitada e o bloco de solicitação é solicitado e o bloco de solicitação é adicionado para o bloco de solicitação.
Quando é a vez do processo de saída de spool para ocupar a CPU, o processo de saída de spool verifica primeiro se existem blocos de saída no bloco de solicitação que aguardam a saída da saída e, se não houver, ele entra no estado de espera. Caso contrário, a saída será executada e, em seguida, o espaço de saída de saída e o bloco de saída solicitado correspondente são liberados, e o processo do usuário que está dormindo porque não há blocos de saída disponíveis.
O processo de saída de spool e o processo do usuário podem ser executados simultaneamente. Este artigo abstrai o processo de um processo de execução (o processo não termina necessariamente após a execução) em uma função, cada vez que gera um número aleatório e executa um determinado processo de acordo com o número aleatório. Se o processo for bloqueado devido a determinadas situações, o próximo número aleatório será gerado e outro processo será agendado. O processo do usuário e o processo de saída de spool estão agendados, por sua vez, por vários motivos, ou seja, execução simultânea.
As funções de todo o sistema são divididas nas seguintes partes: função de inicialização, função de programação, função do processo do usuário e função de saída de spool. A função de inicialização é usada para implementar a entrada e armazenamento inicial de arquivos de usuário; A função de despacho implementa a alternância entre os processos do usuário e os processos de saída de spool; A função do processo do usuário implementa uma série de ações concluídas após a programação do processo; A função de saída de spool representa a operação de saída.
O fluxograma geral da operação do sistema é mostrado na Figura 1:
O sistema primeiro usa a função de inicialização para inicializar a entrada de conteúdo pelo usuário e, em seguida, gera um número aleatório R entre 0 e 1, e julga se o processo do usuário deve ser executado ou o processo de saída deve ser executado de acordo com o tamanho da R. após o processo do usuário e o processo de saída forem executados, o programa é executado, caso contrário, o agendamento continuará.
O usuário precisa inserir o conteúdo que deseja "imprimir". A função de inicialização aceita a entrada de conteúdo pelo usuário e a corta de acordo com o caractere final do arquivo, e coloca o arquivo cortado em uma matriz e o envia para a saída bem quando o processo do usuário estiver agendado.
A programação de processos usa um algoritmo aleatório e a probabilidade de agendamento dos dois processos do usuário solicitando a saída é de 45%, e o processo de saída de spool é de 10%. Este artigo usa números aleatórios para atingir esse requisito. Ao executar a programação do processo, um decimal entre 0 e 1 é gerado aleatoriamente. Se o número for menor ou igual a 0,45, o processo do usuário A será colocado em operação; Se o número estiver entre 0,45 e 0,9, o processo do usuário B será colocado em operação; Se o número for maior que 0,9, o processo de saída de spool será colocado em operação.
A função do processo do usuário precisa primeiro verificar se o processo atual atende a três condições: o arquivo não é emitido, o espaço restante no poço de saída pode abaixar o arquivo e existe um bloco de solicitação de saída disponível. Se as três condições forem atendidas, o arquivo será enviado bem para a saída e o bloco de solicitação correspondente será solicitado.
O fluxograma da execução da função do processo do usuário é mostrado na Figura 2:
Quando o processo do usuário é executado, se for constatado que o arquivo foi emitido, o processo será executado. Caso contrário, é determinado se existe algum espaço restante na saída bem e nenhum estado de espera é inserido. Se houver espaço bem na saída, continue julgando se houver um bloco de saída. Se houver um, envie o arquivo para a saída bem e solicite um bloco de saída e acorde o processo de saída potencialmente sonolento; caso contrário, digite o estado de espera 3.
A função de saída de spool verifica se existem blocos de solicitação de saída e, se houver, recursos e liberações relevantes. Caso contrário, o processo de saída de spool esperará.
O fluxograma da função de saída de spool é mostrado na Figura 3:
A definição de PCB é a seguinte:
class PCB {
/*
* 进程描述
*/
public int id ; //序号
public int status ; //状态,0表示可执行,123表示三个等待状态,4表示结束
public string [ ] contents = new string [ MaxFileCount ] ; //要输出的内容
public int [ ] flags = new int [ MaxFileCount ] ; //为1表示该文件已经被输出,初始全部为0
public int fileCount ; //用户真实输入的文件个数
}O processo do usuário inclui o ID do número de série, o status do processo, o conteúdo a ser emitido, os sinalizadores de saída do arquivo e a contagem real de arquivos.
Entre eles, os possíveis estados do processo em que o processo do usuário pode existir incluem: 0 significa estado executável, 1 significa que o estado de espera 1, 3 significa o estado de espera 3, 4 significa terminar o processo.
O outputReqBlock é definido da seguinte forma:
class OutputReqBlock {
/*
* 输出请求块
*/
public int id ; //要求进行输出的进程的id
public int start ; //文件在输出井中的起始位置
public int length ; //文件长度
public int fileIndex ; //要输出文件的序号
public OutputReqBlock ( int id , int start , int length , int fileIndex ) {
this . id = id ;
this . start = start ;
this . length = length ;
this . fileIndex = fileIndex ;
}
}O bloco de saída de solicitação inclui: o ID do processo do bloco de solicitação, a posição inicial do arquivo no poço de saída, o comprimento do comprimento do arquivo e o número de sequência do arquivo a ser emitido em todos os arquivos do usuário.
A definição de outputwell é a seguinte:
class OutputWell {
/*
* 输出井
*/
public char [ ] buffer = new char [ MaxWellLen ] ; //输出缓冲区
public int begin = 0 ; //当前可用位置
public int restSize = MaxWellLen ; //剩余容量
}Os parâmetros do poço de saída são: Buffer Buffer, usado para armazenar dados colocados pelo usuário; O local atual disponível começa, os arquivos são armazenados em ordem no poço de saída e o início sempre aponta para a posição inicial do buffer atualmente disponível; A capacidade restante repousa, a capacidade restante no buffer, inicialmente o tampão do tampão Maxwelllen.
O usuário insere as informações para "imprimir" na caixa de texto e seleciona a qual processo o conteúdo de saída pertence (a ou b). Por fim, clique no botão de inicialização para iniciar a função de inicialização. A função de inicialização primeiro usa um objeto String para armazenar a entrada de conteúdo pelo usuário. Em seguida, verifique se o conteúdo inserido pelo usuário termina com um número # e solicite que o usuário entre novamente se não for legal. Após a entrada legal, o conteúdo inserido pelo usuário é cortado de acordo com o número # e a string é cortada em várias strings. Finalmente, um objeto PCB é inicializado usando as informações geradas e colocado na fila de espera de espera.
Como o usuário pode clicar no botão de inicialização várias vezes, é necessário determinar se o processo atual foi inicializado antes de cada clique. Se o usuário já tiver concluído a inicialização, mas clicou no botão de inicialização novamente, o conteúdo original será substituído.
O poço de saída é inicializado automaticamente quando a interface do sistema é carregada.
O código da função de inicialização é ignorado!
Para alcançar a aleatoriedade, cada vez que você deseja agendar, um número aleatório entre 0 e 1 é gerado usando a função aleatória de C#. Se o número aleatório for menor ou igual a 0,45 significa que o processo do usuário A será agendado a seguir; Se o número aleatório estiver entre 0,45 e 0,9 significa que o processo do usuário B será agendado a seguir; Se o número aleatório for maior que 0,9 significa que o processo de saída de spool será agendado a seguir.
A implementação da função do agendador é a seguinte:
private int dispatch ( ) {
/*
* 进程调度
*/
double res = rd . NextDouble ( ) ; //产生一个01之间的小数
if ( res <= 0.45 ) {
return 0 ;
} else if ( res <= 0.9 ) {
return 1 ;
} else {
return 2 ; //012分别表示两个进程和SPOOLing输出进程
}
} Usado para implementar uma série de operações executadas quando o processo do usuário está em execução.
Quando o processo do usuário estiver agendado, verifique primeiro se ainda existem arquivos que não foram enviados para a saída bem. Se não houver, o processo atual do usuário será definido para o estado final e a função retorna.
O processo do usuário ainda não terminou, o que significa que ainda existem arquivos que não foram enviados para a saída bem. Loop para encontrar um bloco de arquivo que não tenha sido emitido (o sinalizador correspondente é 1) e, em seguida, consulte se o espaço restante no poço de saída ainda pode colocar esse bloco de arquivo. Caso contrário, defina o estado do processo para aguardar o estado 1 e a função retornar. Se ainda houver espaço, verifique se ainda há um bloco de saída de solicitação disponível. Se o processo não estiver definido para esperar o estado 3, a função retornará. Caso contrário, o bloco de arquivos é enviado bem para a saída e os parâmetros relevantes do poço de saída são modificados. Em seguida, um bloco de saída de solicitação é aplicado à fila de saída PrintQueue e a saída de impressão é impressa quando o processo de saída de spool está agendado. Finalmente, se o processo de saída de spool estiver em um estado de espera, o processo do usuário precisará acordá -lo.
Várias situações durante a função do processo do usuário são salvas através de uma lista para a exibição final do resultado. A lista inclui: o número da sequência de agendamento atual, o número do processo, o status do processo, o status do poço de saída, o número de blocos de solicitação disponíveis, o número da sequência do arquivo e o comprimento do arquivo.
O código da função do processo do usuário é ignorado!
A função da função de saída é selecionar um bloco de saída de solicitação e emitir o conteúdo e, finalmente, liberar o recurso correspondente.
Primeiro verifique se o poço de saída está vazio. Se o processo de saída vazio estiver definido para aguardar o estado 2, a função retornará. Caso contrário, verifique se existem blocos de saída de solicitação na fila de saída de solicitação que precisam ser emitidos e nenhuma função retorna. Caso contrário, o bloco de saída de solicitação na cabeça da fila é obtido na fila de saída da solicitação e, em seguida, o bloco de solicitação é em saída, e o espaço de poço de saída correspondente e o bloco de solicitação são liberados.
Ao emitir a função de saída, o conteúdo de saída deve ser exibido na área de saída do arquivo.
O código da função de saída é ignorado!
O usuário clica no botão "Execução do programa" e começa a executar a função principal. O processo de execução é ajustado dinamicamente de acordo com a situação atual.
A função principal determina primeiro se os dois processos do usuário foram inicializados e só podem ser executados após a inicialização, caso contrário, será relatado um erro.
Após a inicialização, clique no botão "Executar" novamente. Enquanto houver um processo que não esteja no estado final, ou um bloco de solicitação não tenha sido produzido, continue a agendar. Ao agendar, você deve determinar se o processo atual terminou e produzir o estado relevante quando for concluído.
O código de função principal é ignorado!
A descrição de vários parâmetros usados no experimento é mostrada na Tabela 1:
| Nome do parâmetro | Maxwelllen | MaxfileCount | BlockCount |
|---|---|---|---|
| Descrição do parâmetro | Saída de comprimento do poço | O número máximo de arquivos que um usuário pode gerar | Número de blocos solicitados |
| Valor do parâmetro | 15 | 10 | 3 |
A interface do sistema é mostrada na Figura 4:
A interface do sistema é dividida em três seções: inicialização, processo de agendamento e área de saída de arquivos. A seção de inicialização contém uma caixa de texto, uma caixa de seleção e um botão. O usuário insere o arquivo a ser impresso na caixa de texto e o inicializa. A seção do processo de agendamento é principalmente uma tabela que exibe o processo detalhado de agendamento de processos. A seção de saída do arquivo é usada para exibir o processo de impressão de todos os arquivos.
O usuário primeiro seleciona um processo, o padrão inicial é A e, em seguida, coloca o arquivo a ser emitido na caixa de texto da seção de inicialização e, em seguida, clica no botão de inicialização. A inicialização é bem -sucedida, como mostrado na Figura 5:
Para o processo B, execute as operações acima, como mostrado na Figura 6:
Após a inicialização dos dois processos do usuário, clique no botão Executar programa e os resultados são mostrados na Figura 7 e na Figura 8:
A seguir, é apresentada uma breve análise do conteúdo da Figura 7. Como mostrado na Figura 9:
O processo de saída foi agendado pela primeira vez, porque a saída está vazia neste momento, portanto, o estado do processo de saída está esperando o estado 2 e o número de blocos de solicitação disponível é 3. Na segunda vez que o processo A está agendado. O estado do processo A é executável. O número de blocos de solicitação disponível é 3. A envia o arquivo 0 para a saída bem. O comprimento do arquivo 0 ("ABCD") é 4. O processo de saída está agendado pela terceira vez. O espaço disponível do poço de saída é 15-4 = 11, o número de blocos de solicitação disponível se torna 2 e o arquivo 0 do processo A é a saída, conforme mostrado na área de saída do arquivo, e o espaço relevante é liberado.