Infra - Linux

Linux - IPCMSG: Comunicação inter-processos sem magia negra

A biblioteca IPCMSG foi criada para facilitar o desenvolvimento de programas que utilizam comunicação inter-processo. Nesse artigo aprenderemos, de forma prática, como usar essa biblioteca em seus códigos C/C++. O projeto se encontra em fase embrionária, portanto é fundamental ajudas, CRÍTICAS e/ou sugestões para amadurecimento do projeto.

por Alessandro de Oliveira Faria



Introdução

A biblioteca IPCMSG foi criada para facilitar o desenvolvimento de programas que utilizam comunicação inter-processo.

A IPCMSG disponibiliza os seguintes recursos:

  • Semáforos: Utilizados para sincronizar dois ou mais processos;
  • Fila de mensagens: Em sistemas Unix/Linux, este recurso é utilizado para troca eficaz de dados entre processos;
  • Sinais: Interrupção de software assíncrona utilizada para time-out nas comunicações inter-processos;
  • Sockets: Utilizados para troca de informações entre processos locais e remotos via rede.

Onde utilizamos a IPCMSG?

A biblioteca IPCMSG permite a utilização sem segredo dos recursos de comunicação inter-processos. Um ou mais processos podem comunicar entre si através da troca de mensagens.

A troca de mensagens podem ser sincronizadas ou não dependendo da aplicação em desenvolvimento. Utilizado semáforos em caso de um aplicação com processo sincronizados, assim garantindo a organização nas sincronização dos processos.

Em caso de falha durante um determinado processamento, um processo pode eventualmente não responder a uma mensagem. Para contornar este problema, usamos o recurso de sinais. Sinais são interrupções de software assíncrona que em nosso caso serve com time-out dos envios de mensagens.

Download, instalação e compilação

O download deve ser efetuado em:


Abaixo as instruções passo-a-passo para a instalação da biblioteca.

Use o comando "tar -zxvf" para extrair todo o pacote (fontes e exemplos):

$ tar -zxvf ipcmsg-0.90-20050903.tar.gz
ipcmsg-0.90-20050903/exemplo/
ipcmsg-0.90-20050903/exemplo/tcp/
ipcmsg-0.90-20050903/exemplo/tcp/cliente.cpp
ipcmsg-0.90-20050903/exemplo/tcp/server.cpp
ipcmsg-0.90-20050903/exemplo/comunica/
ipcmsg-0.90-20050903/exemplo/comunica/cliente.cpp
ipcmsg-0.90-20050903/exemplo/comunica/server.cpp
ipcmsg-0.90-20050903/exemplo/semaforo/
ipcmsg-0.90-20050903/exemplo/semaforo/cliente.cpp
ipcmsg-0.90-20050903/exemplo/semaforo/server.cpp
ipcmsg-0.90-20050903/lib/
ipcmsg-0.90-20050903/lib/Makefile
ipcmsg-0.90-20050903/lib/funcoesIPC.cpp
ipcmsg-0.90-20050903/lib/funcoesIPC.h
ipcmsg-0.90-20050903/lib/funcoesTCP.h
ipcmsg-0.90-20050903/lib/funcoesTCP.cpp

Ao entrar na pasta criada pelo comando tar, verifique o seu conteúdo com o comando "ls". Encontraremos a pasta lib com os fontes da biblioteca, já na pasta exemplo teremos alguns códigos para demonstrar a funcionalidade da biblioteca IPCMSG.

$ cd ipcmsg-0.90-20050903/
$ ls -l
total 0
drwxr-x---  5 cabelo users 120 2005-09-03 14:44 exemplo
drwxr-x---  2 cabelo users 200 2005-09-03 14:44 lib

Para compilar e instalar a biblioteca, entre na pasta lib e execute o 
comando make. Após a compilação, execute o comando make install como 
super-usuário: 

$ cd lib/
$ su
# make
# make install


Agora vamos aos exemplos, entre na pasta exemplo e efetue o comando ls conforme o comando abaixo:

$ cd ..
$ ls
$ cd exemplo/
$ ls -l
total 0
drwxr-x---  2 cabelo users 112 2005-09-03 14:44 comunica
drwxr-x---  2 cabelo users 112 2005-09-03 14:44 semaforo
drwxr-x---  2 cabelo users 112 2005-09-03 14:44 tcp

Para não tornar muito extenso este artigo, irei explicar apenas a 
comunicação inter-processo através da fila de mensagem. 

Entre na pasta comunica. Ao visualizar o seu conteúdo com o ls, note que existem 2 arquivos fonte, o cliente e o server.

$ cd comunica/
$ ls -l
total 8
-rw-r-----  1 cabelo users  779 2005-09-03 14:44 cliente.cpp
-rw-r-----  1 cabelo users 1100 2005-09-03 14:44 server.cpp

Para compilar, use o compilador g++ como no exemplo abaixo, assim obtendo 
os 2 binários para execução dos nossos testes: 

$ g++ cliente.cpp -o cliente -lIPCMSG
$ g++ server.cpp -o server -lIPCMSG
$ ls -l
total 88
-rwxr-xr-x  1 cabelo users 37965 2005-09-03 15:01 cliente
-rw-r-----  1 cabelo users   779 2005-09-03 14:44 cliente.cpp
-rwxr-xr-x  1 cabelo users 38072 2005-09-03 15:01 server
-rw-r-----  1 cabelo users  1100 2005-09-03 14:44 server.cpp

Antes de executar os nossos programas teste, execute o comando ipcs: 


$ ipcs
- Segmentos da memória compartilhada -
chave      shmid   proprietario perms bytes   nattch status
0x00000000 851969  cabelo       600   262144  1      dest
0x00000000 917506  cabelo       600   393216  2      dest
0x00000000 950275  cabelo       600   196608  2      dest
0x00000000 4292612 cabelo       600   393216  2      dest
0x00000000 4325381 cabelo       600   196608  2      dest
0x00000000 4358150 cabelo       666   57600   1      dest

------ Arrays de semáforos ------
chave      semid      proprietario perms      nsems

----- Filas de mensagens ------
chave  msqid   proprietario perms  bytes usados mensagens

Reparem que não existe nenhuma fila de mensagem criada até o presente 
momento. Agora execute o programa server e veja o que acontece ao executar o 
ipcs em outro terminal: 

$ ./server
[PID 8132] Fila (13) ID:65537 criada com sucesso.
SERVER: Aguardando MSG...

Ao executar o programa server com PID 8132, a fila de mensagem com o ID 65537 foi criada com na chave 13 (D em hexadecimal). Para constatar estes dados e verificar se a fila foi criada com sucesso, execute o comando ipcs novamente:

$ ipcs
- Segmentos da memória compartilhada -
chave      shmid   proprietario perms bytes  nattch status
0x00000000 851969  cabelo       600   262144 1      dest
0x00000000 917506  cabelo       600   393216 2      dest
0x00000000 950275  cabelo       600   196608 2      dest
0x00000000 4292612 cabelo       600   393216 2      dest
0x00000000 4325381 cabelo       600   196608 2      dest
0x00000000 4358150 cabelo       666   57600  1      dest

------ Arrays de semáforos ------
chave      semid   proprietario perms  nsems

----- Filas de mensagens ------
chave      msqid proprietario perms bytes usados mensagens
0x0000000d 65537 cabelo       666   0            0

Agora vamos executar o programa cliente (em outro terminal) para efetuar a 
comunicação entre os dois processos criados (o server e o cliente). 

$ ./cliente
[PID 8134] Processo conectado com sucesso na fila 13 ID:65537

Neste momento criamos dois processos o server com PID 8132 e o cliente com o PID 8134. Quando o cliente é executado, ele se conectar com a fila de mensagem e aguardar a digitação de uma string para ser enviada ao processo server através da fila de mensagem.

PID.:8134> olá processo pai
[PID 8134] Aguardando ACK

Ao digitarmos "olá processo pai" seguido da tecla [ENTER], automaticamente o cliente aguarda uma resposta do processo server.

SERVER: Aguardando MSG...
PID.:8132> olá processo pai
PID.:8132>

Já o processo server recebe a mensagem e aguarda a digitação da resposta a ser enviada ao processo cliente.

[SIGNAL] Time Out!
[PID 8134] Erro na recepção na Fila ID:(65537) - (Interrupted system call)

Propositalmente, não digitei nenhuma mensagem. Com isto provoquei uma interrupção de software assíncrona através de sinais.

PID.:8132>
SERVER: Aguardando MSG...

Por sofrer um SINAL de TIME-OUT, o processo server volta a guarda a nova mensagem do processo cliente.

PID.:8134> olá novamente processo pai ok?
[PID 8134] Aguardando ACK

Agora vamos enviar a mensagem ao processo server e responder imediatamente.

SERVER: Aguardando MSG...
PID.:8187> olá novamente processo pai ok?
PID.:8187> ok
SERVER: Aguardando MSG...

Ao digitar "ok" no processo server, imediatamente envia a mensagem ao processo cliente, confirme no terminal que esta sendo executado o programa cliente.

PID.:8134> ok

Com esta biblioteca, podemos desenvolver programas que permitem troca de mensagens inter-processo sem grande esforço/técnica de programação.

Maiores informações podem ser obtida na sessão documentação do link oficial do projeto:
Alessandro de Oliveira Faria

Alessandro de Oliveira Faria - Sócio-proprietário da empresa NETi TECNOLOGIA fundada em Junho de 1996 (http://www.netitec.com.br), empresa especializada em desenvolvimento de software e soluções biométricas, Consultor Biométrico na tecnologia de reconhecimento facial, atuando na área de tecnologia desde 1986 assim propiciando ao mercado soluções em software nas mais diversas linguagens e plataforma, levando o Linux a sério desde 1998 com desenvolvimento de soluções open-source, membro colaborador da comunidade Viva O Linux, mantenedor da biblioteca open-source de vídeo captura entre outros projetos.