domingo, 23 de setembro de 2012

Entendendo Processos do Unix com Programas em C – Parte 2 – Criação de Processos

Continuando a replicação do trabalho do meu amigo Joelson:



Como Funciona a Criação de Processos
Os processos pai criam processos filhos, que, por sua vez, criam outros processos, formando uma árvore de processos.
Durante a execução, pai e filhos são executados concorrentemente, porém o pai espera até que os filhos terminem suas execuções.
Um ponto interessante a se observar é que quando o processo pai gera um processo filho, na verdade o processo filho é exatamente a cópia do processo pai, porém o filho pode ou não carregar um novo programa nele para que tenha outro conteúdo.
Nos sistemas Unix, as chamadas de sistema (system-call)
  • fork cria novo processo (processo filho)
  • exec que é usada após o fork substitui o espaço de memória do processo por um novo programa
  • wait faz com que o processo pai permaneça bloqueado até seus filhos terminarem suas execuções.
Quando um processo é criado, um novo bloco de controle de processo (PCB) é criado para o processo.
Quando o fork é executado, o sistema copia o processo corrente e o executa. O valor de retorno de todo processo filho é ’0′ (zero), enquanto do processo pai é retornado o identificador (process identification – pid) do processo filho. Normalmente usamos o valor de retorno para identificarmos se o processo que está executando é o pai ou o filho.
Colocando a Mão na Massa
Para testarmos os conceitos acima ditos, vamos para mais um programinha em C:


 #include <stdio.h>  
 #include <sys/types.h>  
 #include <unistd.h>  
 int main() {  
   if(fork() == 0) {  
     printf(“Eu sou o filho\n”);  
   } else {  
     printf(“Eu sou o pai\n”);  
   }  
 }  

Para compilarmos o arquivo:

gcc -o ProcessosPaiFilho ProcessosPaiFilho.c
E para executarmos:
./ProcessosPaiFilho
Repare que nossa saída foi:
Eu sou o pai
Eu sou o filho
Explicando o conteúdo do programa acima, podemos reparar o seguinte:
Quando no primeiro ‘if’ chamamos a função fork(), é gerado e processado um novo processo filho e que é cópia deste mesmo programa. Ambos são executados em paralelo. No processo filho, que o retorno da função fork() é comparado com zero (como vimos nos conceitos anteriores, o processo filho retorna zero no fork()), será impresso na tela “Eu sou o filho”. No processo pai, o bloco ‘else’ será executado, imprimindo na tela “Eu sou o pai”.
Conclusão
Vimos mais um passo de como funcionam os processos no sistema operacional com base Unix. Vamos continuar avançando e publicando evidências dos estudos!



sexta-feira, 21 de setembro de 2012

Atalhos do Terminal no MAC Os

Resolvir postar alguns atalhos para ajudar a trabalhar no TERMINAL do MAC. Os atalhos ajudam bastante a vida de quem trabalha com o terminal

FunçãoAtalho
Ctrl + AIr para o início da linha atual
Ctrl + EIr para o fim da linha atual
Ctrl + KApaga tudo o que estiver após o cursor
Ctrl + UApaga tudo o que estiver antes do cursor
Ctrl + WApaga a palavra antes do cursor
Ctrl + LLimpa todo o buffer do terminal atual
Ctrl + RBusca comandos previamente utilizados
Ctrl + C"Mata" a linha atual
Ctrl + Z Interromper qualquer comando em execução 

E se você sente falta de alguma tecla de atalho, ou gostaria de modificar alguma já existente, essa dica é para você. Em "System Preferences › Keyboard & Mouse › Keyboard Shortcut", você pode adicionar os atalhos para um programa específico, ou para todos!
Painel de Preferências de Teclado e Mouse


Um outra dica interessante é adicionar o Terminal nas pasta do FINDER. 


Para isso basta:


Para ativar este recurso, abra as Preferências do Sistema e vá em Teclado. Na aba Atalhos de teclado, escolha Serviços na lista à esquerda e, após isso, na subseção Arquivo, vá em New Terminal at Folder (ou New Terminal Tab at Folder).
Enquanto estiver nessa tela, é possível adicionar atalhos de teclado ao dar um clique duplo no espaço em branco ao lado do nome do comando e escolher um novo atalho. Não esqueça, ao final, de habilitar a caixa para que a função seja ativada. 
Agora, ao dar um clique direito (ou Control+clique) em uma pasta no Finder, um novo Serviço do Terminal irá aparecer na base do menu contextual. Use essa nova opção - ou atalho de teclado - e o Terminal irá abrir uma nova janela (ou aba) com a pasta que foi escolhida pelo usuário.
terminalfolder_01.jpg
Comando pode ser feito no menu contextual ou a partir de um atalho de teclado

Alternar entre Abas no Terminal do MAC Os


Dica Simples mais que ajuda bastante na agilidade do Terminal

⌘+shift+setas 

Utilizando o VIM no Linux

Estou iniciando na edição através do Linux. Portanto resolvi aqui colocar informações importantes para compartilhar com todo.

Usando o editor de texto vim: 

1) Pra abrir o vim digite "vim nomedoarquivo" (sugiro que vocês usem o tab para preencher o nome do arquivo corretamente, pois caso o arquivo não exista o editor se encarregará de criar um; 

2) Para começar a digitar no vim clique no botão "Insert ou i" que se encontra no seu teclado; 

3)Após escrever ou alterar um arquivo, aperte o botão "Esc", depois clique em "shift+: " Para habilitar o modo de opções.

As Opções mais utilizadas são:



  • x - sai e salva o arquivo;

  • q - apenas sai;

  • w - salva;

  • q! - sai forçado (muito útil caso você faça uma alteração e não queira salvar).

  • quinta-feira, 20 de setembro de 2012

    Entendendo Processos do Unix com Programas em C – Parte 1


    Este Post é em homenagem ao trabalho do meu colega de turma Joelson da Cunha Lucena,

    Motivação
    Estou estudando Sistemas Operacionais com base Unix e tenho feito alguns testes em C para comprovar os estudos. Creio que possa ser útil a publicação desses programinhas criados para compartilhar o conhecimento.
    Processos em Sistemas Unix
    Um processo é um programa em execução.
    Vários conceitos permeiam o mundo dos processos, tais como a estrutura de um processo na memória, os possíveis estados de um processo, o bloco de controle de processo (PCB), como o sistema operacional trata os processos durante suas trocas de contexto, filas de escalonamento de processos, os escalonadores propriamente ditos, etc. (Talvez entremos mais a fundo em cada um desses conceitos mais pra frente)
    Como o foco é ser prático, vamos a um exemplo de como podemos gerar um processo em Unix.
    Mãos na Massa
    Estando em algum sistema com base Unix (Linux, Mac OS, BSD, Hurd, etc), vamos criar um arquivo chamado loop.c no qual conterá nosso código de programa na linguagem C. O local de trabalho fica a seu critério, mas no exemplo vou usar o home do meu usuário.
    Dentro do arquivo, criaremos o seguinte código na linguagem C:
    #include
    #include
    int main() {
        while(1);
    }
    O programa começa com a declaração dos includes, que são as bibliotecas que  nos fornecem as funções usadas no nosso código. O ‘int main()’ é a declaração do método principal a ser executado naquele determinado arquivo/programa. Repare que seu conteúdo é apenas ‘while(1)’, o que provocará um loop infinito dentro do programa. Fizemos isso para que você possa ver o processo sendo executado no sistema operacional, então se tivéssemos colocado qualquer programação finda, não seria possível acompanharmos o importante passo que o exercício propõe, que é vermos o processo que criamos em execução.
    Como os arquivos .c não podem ser executados diretamente, devemos compilar o arquivo para criarmos um executável. Para tal, posicionado no terminal na pasta onde consta o arquivo loop.c criado, digite o seguinte comando:
    gcc -o loop loop.c
    onde:
    • gcc -o – é o programa a ser chamado para que o sistema compile o arquivo
    • loop – é o nome do arquivo que será criado
    • loop.c – é o nome do nosso arquivo origem de código fonte.
    Tendo criado o nosso arquivo executável, para chamá-lo, podemos digitar no terminal:
    ./loop&
    onde:
    • ./ – é o indicador de que chamamos determinado arquivo à execução
    • loop – é o nome do arquivo executável que geramos e queremos executar
    • & – Serve para que o sistema rode esse programa em background. Se não tivéssemos especificado esse caracter, o terminal nos bloquearia naquela sessão até que finalizássemos o processo abruptamente.
    Para vermos o nosso processo em execução, podemos digitar no terminal o comando: top
    Ele te retornará uma lista de processos em execução, tal como isto:
     2160 joelson   20   0  4148  352  272 R  100  0.0   2:00.47 loop                                                                                                       
     1149 root      20   0  161m  24m  11m S    1  0.4   1:36.36 Xorg                                                                                                       
     1890 joelson   20   0 1107m 273m  36m S    1  4.7   4:26.13 firefox                                                                                                     1934 joelson   20   0  373m  37m  20m S    1  0.6   0:30.50 plugin-containe    
    Repare que o nosso processo loop é logo o primeiro da minha fila!
    Como o nosso processo é de loop infinito, ele nunca deixará de executar a não ser que o interrompemos.
    Ainda na tela de visualização dos processos em execução, para que você finalize o processo loop, digite k
    Ele aguardará uma entrada com o identificador do processo a ser finalizado. No meu caso, é 2160, então é o que eu digitarei e darei enter.
    Após, ele pede um sinal de finalização. Digite 9 e dê enter novamente. Pronto, finalizamos o processo!
    Para sair da visualização da lista de processos, digite: ctrl + c
    Conclusão
    Entender como funcionam os sistemas operacionais é muito interessante, mas vermos na prática seu funcionamento é muito melhor. Vimos como criamos e, de maneira limitada, que podemos manipular nossos processos e seus estados. Nos estudos que ainda serão postados, vamos nos aprofundando nas especificidades dos processos. Espero que seja de proveito de todos.

    quinta-feira, 26 de abril de 2012

    Consulta SQL de Calculo de Horas no Oracle, considerando o mês atual.

    Boa tarde a todos,

    Hoje encontrei dificuldade em uma consulta SQL no Oracle, que foi resolvida graças a meu colega de trabalho Anderson Santos da Silva vulgo  "Balrog". Vou citar cada linha do código e comenta-la logo abaixo,

    Problema:  Calcular a diferença de TEMPO em minutos entre dois campos.


     AbaixoDATE(data_abertura, data_baixa).  "Ate  esse momento nada de anormal"

    No entanto a consulta precisaria considerar apenas os registros do campo data_baixa do mês corrente.

    Para o calculo de o TEMPO considerar o seguinte:

     Caso o campo data_abertura tivesse registro anterior ao mês atual ele precisaria desconsiderar esse valor e considerar  a data a partir  do dia 01 do mês atual as 00:00:00hs 

    Ou 

    Se o campo data_abertura tivesse data do mês atual, efetuar o calculo normalmente.

    Solucao:

    select

    data_abertura,
    data_baixa,
    case

      --Aqui comparamos se a data de abertura é menor que o mes atual com parando a data do SYSDATE
      --Utilizamos também o TRUNC para mantém apenas a parte desejada de um numéro no caso o mês



       when ADD_MONTHS(TRUNC(data_abertura, 'MONTH'), -0) <
            ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'), -0) then

      --Aqui alem de usar  ROUND que arredonda o valor dada uma posição específica.
      --diminuimos a data_baixa pela função "ADD_MONTHS(TRUNC(SYSDATE, 


      'MONTH'), -0" que retorna o mes atual e 1 dia e 1 hora

     --exatamente o que queriamos 00:00:00hs
      --Depois tranformamos para minutos

        ROUND(((data_baixa - ADD_MONTHS(TRUNC(SYSDATE, 'MONTH'), -0)) * 24 * 60), 2)
       else

      --Aqui fazemos o calculo normal dos dois campos caso esteja dentro do mes atual.
        
    ROUND(((data_baixa - data_abertura) * 24 * 60), 2)
    end as tempo_minutos_f

      from gtt
    ------




    Foi uma resposta simples e inteligente.

    Obrigado Mr. Anderson Balrog