Pular para o conteúdo

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

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!
Perfil removido removido
Hits: 12.282 Categoria: C/C++ Subcategoria: Avançado
  • Download
  • Nova versão
  • Indicar
  • Denunciar

Descrição

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!
Download projeto2.tar Enviar nova versão

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... [
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... [
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"
33[1;32mOK
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"
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"
33[1;32mOK
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... [
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"
33[1;32mOK
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"
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"
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"

Árvore Binária de Busca - ABB

Escaneando diretório

Derrubando Win9x/Win2k !

2° mod do CGI

jogo Sokoban (com gráficos)

Nenhum comentário foi encontrado.

Contribuir com comentário

Entre na sua conta para comentar.