Memória compartilhada, semáforo e criação de processos

Publicado por Perfil removido (última atualização em 17/02/2014)

[ Hits: 11.738 ]

Download projeto2.tar




Dois programas simples em C++ que usam recursos como memória compartilhada, semáforos e criação de processos para comunicarem entre si!

Observação: depois de compilado haverá dois binários, um chamado gerenciador e outro com o nome de cliente. Execute o gerenciador pois o mesmo executará o cliente, e um depende do outro para funcionar corretamente!

  



Esconder código-fonte

Arquivo main.cpp:

#include "foo.hpp"
#include <sys/wait.h>
using namespace std;


int shared_memory_clear();
int myfuction();
char *shared_memory;




int main(){

int shmid;

//Remove o segmento de memoría criado com a chave MY_KEY
//MY_KEY está definido em foo.hpp

shared_memory_clear();


//se esse segmento existir (ver detalhes nos comentários na função shared_memory_clear())



//shmget:para criar um segmento de memória compartilhada
// para mais detalhes execute man shmget

//shmat:retorna um pointeiro para o segmento de memória compartilhada
// man shmat para mais detalhes

 if((shmid=shmget(MY_KEY,1,IPC_CREAT|IPC_EXCL|0644) ) <0 || (shared_memory=(char *)shmat(shmid,0,0) )<0 )
    {
      cerr<<"\nFailhou ao iniciar um segmento de memória"<<endl;
 return -1;
    }else
    cout<<"\nSegmento de Memória... [{FONTE}33[1;32mOK{FONTE}33[0m]"<<endl;


  int status=myfuction();
  if(status==0)
    return 0;    //somente o processo ("child") ira retornar 0 mas
                 // não tenho certeza disso pois o processo ("Child")
                 //executará a função execv()para executar outro binário
                 // deixe ele aqui no caso de dúvidas :)
                 // esse treicho foi necessário quando eu estava testando os semaforos e o segmento de memória
                 //nesse mesmo binario atraves da função fork() mais sem executar nenhum outro binário
                  //mesmo modificando ele para excutar outro binário
                  //decidi não remover: como eu disse em caso de dúvida








  //shmdt: eu uso essa função junto com a função shmctl mais não sei
  //se isso é realmente necessário :)
  //man shmdt para detalhes!

  //shmctl: faz o controle do segmento de memória.No caso usei a opção IPC_RMID para marcar para remoção
  // esse segmento de memória compartilhada
  // man shctl para detalhes

  if ( (shmctl(shmid,IPC_RMID,0))<0||(shmdt(shared_memory)) <0 )
    {
      cerr<<"\nFalhou ao remover o segmento de memória!"<<endl;
      return -1;
    }


  return 0;
}






//////////////////////////////////////////////////////



int myfuction()
{

  //Cria um semaforo nomeado para impedir que os dois programas tentem acessar
  //o segmento de memória ao mesmo tempo!
  // execute man sem_open para mais detalhes
  sem_t *SEM=sem_open(MY_FILE,O_CREAT|O_EXCL,644,1);
  if(SEM==SEM_FAILED)
       {
     cerr<<"\nFalhou ao criar um semaforo!"<<endl;
     return -1;
       }



//remove o semaforo.
//Se algum processo estiver usando ele a chamada da função sem_unlink é adiada
// para mais detalhes execute man sem_unlink

  if ((sem_unlink(MY_FILE))<0)
 cerr<<"\nFailed to unlik semaphore file"<<endl;




  int child=fork(); //cria um novo processo semelhante ao em execução

 if(child<0)
   {
     cerr<<"\nFailed to create child process"<<endl;
return -1;
}





 if(child==0) //esse trecho só será executado pelo processo recem criado("child")
   {
     ////////////////////////////////////////////
     //////////////////child process////////////
     //////////////////////////////////////////
     execv("cliente",NULL);


     return 0;

 } else {
   //esse trecho só será excutado pelo processo pai ("parent");


     /////////////////////////////////////////////////////
     ////////////////////Parent process//////////////////
     ////////////////////////////////////////////////////
   int status;
     string line;
     //vai encerrar se o programa cliente escrever na
     //memória compartilhada exit
     while(line!="exit")
      {
    usleep(500000); //espeara um periodo curto de tempo antes de executar o
                    //resto do código ("Taxa de atualização :)")
    sem_wait(SEM);
    line=shared_memory; //vai colocar o conteudo do pointeiro que aponta para
                        //um segmento de memória compartilhada
    sem_post(SEM);
      }
     waitpid(child,&status,0);
     cout<<"\nCliente terminou com status"<<"("<<status<<")";
     cout<<"\nSaindo"<<endl;
     return 1;

}




}







//Função para remover o segmento de memoria criado com a chave "MY_KEY"
//mais que pode nao ter sido removido por algum motivo,como encerramento do programa
//antes de ele naturalmente remover o segmento !
int shared_memory_clear()
{
  int shmid_del=shmget(MY_KEY,0,IPC_CREAT);
  if(shmid_del >0){
    cout<<"\nSegmento de memória compartilhada encontrada"<<endl;

    if(( shmctl(shmid_del,IPC_RMID,0))<0)
      {
    cerr<<"\nFalhou ao tentar remover o segmento de memória compartilhada "<<endl;
    return -1;
      }

    cout<<"\nSegmento de memória compartilhada encontrada removida"<<endl;
}




Arquivo cliente.cpp:


#include "foo.hpp" // meio sem criatividade eu! não acha? foo.hpp
using namespace std;

int myfuction();

char *shared_memory;
int main()
{
  int shmid=shmget(MY_KEY,0,IPC_CREAT); //colocamos a mesma chave do gerenciador aqui mais sem a flag IPC_EXCL a função não vai criar outro segmento se esse ja
  //existir
  if(shmid<0)
    {
      cerr<<"\nFalhou em shmid"<<endl;
      return -1;
    }
  shared_memory=(char *)shmat(shmid,0,0);// pointeiro para o segmento
  if(shared_memory<0)
    {
      cerr<<"\nFalhou em shmat"<<endl;
 return -1;
    }

  myfuction();




  return 0;
}



int myfuction(){
  sem_t *SEM=sem_open(MY_FILE,O_CREAT,0,1); //abri o semaforo ja existente

  if(SEM==SEM_FAILED)
    {
      cerr<<"\nFalhou em sem_open"<<endl;
      return -1;
    }

  if(( sem_unlink(MY_FILE))<0) //mesmo caso descrito no código do gerenciador
    {
      cerr<<"\nFalhou em sem_unlink"<<endl;
      return -1;
    }




////////////////ITER COMUNICATION AREA!///////////////////

 string line;
 while(line!="exit") //só ira sair se voce digitar exit
   {
     cout<<"\nEscreva algo: ";
     getline(cin,line);
     sem_wait(SEM);
     strcpy(shared_memory,line.c_str());
     sem_post(SEM);

     cout<<"\nVoce escreveu "<<shared_memory<<endl;
   }

///////////////END OF INTER COMUNICATION AREA!/////////////








     return 0;



}



Arquivo foo.hpp:


#include <iostream>
#include <cstring>
#include <unistd.h>
#include <sys/shm.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <semaphore.h>
#define MY_KEY 11111
#define MY_FILE "file_for_semaphore"

Scripts recomendados

S. MarioBros - Editor de fase 0.1

Função HASH em C++

Derrubando Win9x/Win2k !

Ordenação quicksort

Joguinho de labirinto usando as setas do teclado


  

Comentários

Nenhum comentário foi encontrado.


Contribuir com comentário




Patrocínio

Site hospedado pelo provedor RedeHost.
Linux banner

Destaques

Artigos

Dicas

Tópicos

Top 10 do mês

Scripts