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

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

[ Hits: 11.735 ]

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

Minishell

Braco Robotico em OpenGL

Rotação à esquerda árvore Binária

Fila em C

RPN (Notação Polar Revesa)


  

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