Memória compartilhada, semáforo e criação de processos
Publicado por Perfil removido (última atualização em 17/02/2014)
[ Hits: 11.569 ]
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!
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"
Árvore de busca binária com frequência de consultas
AA linux kernel modificado por minhe
Nenhum comentário foi encontrado.
Deixando o Gnome bonitão em qualquer distribuição
Como ativar o módulo de cancelamento de ruído no Pipewire
Como escolher o melhor escalonador de CPU para melhorar o desempenho da máquina
Curiosidade sobre DOOM Guy e Isabelle de Animal Crossing
Inicializando servidor Ubuntu na AWS e rodando apache em Container
Como fazer um pendrive butável dar boot no VirtualBox
Corrigindo Saída de Som Invertida no Linux
Problema com o Apache NetBeans IDE 21 no Debian 12 (5)
GRUB do Debian 12 não detecta segundo Linux instalado em partição BTRF... (28)
executar arquivo como programa pelo terminal linux ubuntu (5)
Me ajudem a corrigir esse erro que está dando no meu Virtual Box! (3)