comunicação entre processos(ipc) em c/linux
Post on 13-Aug-2015
394 Views
Preview:
DESCRIPTION
TRANSCRIPT
U N I V E R S I D A D E L U S Í A D A D E L I S B O A
F a c u ld ad e de C i ê nc i as d a Ec o n o mí a e d a Em p re s a
Mestrado em Ciências da Computação
Primeiro relatório de Comunicação entre processos (IPC)
Hercílio Rui Dinis Duarte
Lisboa
Maio 2012
U N I V E R S I D A D E L U S Í A D A D E L I S B O A
F a c u ld ad e de C i ê nc i as e d a Ec o no mí a d a Em p re s a
Mestrado em Ciências da Computação
Primeiro relatório de comunicação entre processos (IPC)
Hercílio Rui Dinis Duarte
Lisboa
Maio 2012
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 13
SUMÁRIO
1. Introdução .................................................................................................... 14
2. Breve abordagem sobre o Linux .................................................................. 15
2.1. Utilizadores, tarefas e processos ........................................................... 15
2.2. Sistema de ficheiros............................................................................... 15
3. Comunicação entre processos (IPC) ........................................................... 16
3.1. Tipos de IPC .......................................................................................... 16
3.1.1. Pipes ............................................................................................... 16
3.1.2. Filas de Mensagens ........................................................................ 16
3.1.3. Memória partilhada .......................................................................... 16
3.2. Sincronização entre processos .............................................................. 17
3.2.1. Sinais ............................................................................................... 17
3.2.2. Semáforos ....................................................................................... 17
3.3. A Correção dos programas .................................................................... 17
3.3.1. O programa sobre pipes .................................................................. 17
Variáveis declaradas ................................................................. 17 3.3.1.1.
3.3.2. O Programa sobre Filas de mensagens .......................................... 18
Variáveis declaradas ................................................................. 19 3.3.2.1.
3.3.3. Sinais ............................................................................................... 20
3.3.4. Socketpair ....................................................................................... 21
Variáveis declaradas ................................................................. 21 3.3.4.1.
3.4. O Programa da memória partilhada ....................................................... 22
4. Conclusão .................................................................................................... 25
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 14
1. INTRODUÇÃO
Este trabalho surge com o objectivo prático de fazer o estudo sobre a comunicação
entre processos.
De formas a se perceber os conceitos, foram propostos a análise de erros em
programas criados, fazer correções e a seguir fazer uma comparação com outros
programas de maneiras a interiorizar a aplicação e diferença entre alguns tipos de
IPC.
De forma a entrar bem no tema, farei uma breve abordagem conceptua do termo
“Linux”, baseando em definições de alguns autores e logo a seguir é que entrarei nos
IPC.
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 15
2. BREVE ABORDAGEM SOBRE O LINUX
2.1. UTILIZADORES, TAREFAS E PROCESSOS
O sistema operativo linux é um sistema multitarefa e multiutilizador. Isso implica que o
sistema tem de impedir que os utilizadores possam interferir no trabalho uns dos
outros. Este conceito respeita exactamente o principio da confidencialidade.
(PEREIRA Paulo, 2005)
O Linux é tido como um dos sistemas operativos mais seguros, devido a aplicação do
coneceito de Superutilizador. Para alterarmos ficheiro do sistema precisamos estar
logados como root, isto significa que o aconselhável para um utilizador é de jamais
acessar com os privilégios de Superutilizador.
Segundo FERREIRA (2005), os poderes de Superutilizador são quase infinitos e por
isso esse modo deve ser sempre usando cuidados, porque qualquer erro pelo
utilizador root pode causar consequências desastrosas.
Suponhamos que existe a tentativa de envio de virus para um sistema Linux, este não
poderá propagar-se devido a realidade de muitos utilizadores estarem logados com
privilégios normais.
A tentativa do Linux como um sistema operativo Open Source tornou-o bastante forte
e robusto. Pois o código fonte de suas versões estão disponíveis para que possam ser
utilizados por qualquer pesssoa, de maneiras a permitir uma continuidade para a
comunidade que utiliza.
2.2. SISTEMA DE FICHEIROS
A origem da árvore de directorias do sistema Linux é marcada pela directoria root que
é representada pelo caracter “ / ”. A seguir ao root existem as subdirectorias descri na
tabela a seguir:
“The most exciting developments for Linux will happen in user space, not kernel space. The changes in the kernel will seem small compared to what’s happening further out in the system.” Linus Trovalds
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 16
Directório Descrição /bin Arquivos binários de comandos essenciais do
sistema.
/boot Arquivos do arranque do sistema
/dev
Contém ficheiros que representam todos os dispositivos de hardware e periféricos de sistema.
/etc Contém a maioria dos ficheiros de configuração do sistema operativo.
/home Diretórias de trabalho do utilizador.
/lib Contém bibliotecas necessárias para que o sistema e os programas possam funcionar.
/mnt Diretório de montagem de dispositivos, sistemas de arquivos e partição
/opt Para instalação de programas não oficiais da distribuição.
/proc Diretório virtual (RAM) onde rodam os processos ativos.
/root Diretório local do superusuário (root).
/sbin Arquivos de sistema essenciais (binários do superusuário).
/tmp Arquivos temporários gerados por alguns utilitários.
/usr Arquivos de usuários nativos da distribuição.
/usr/local Para instalação de programas não oficiais da distribuição.
/usr/src Arquivos fontes do sistema necessários para compilar o kernel.
/var Arquivos de log e outros arquivos variáveis.
3. COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Que em inglês significa Inter-Process Communication, trata-se de um conjunto de
mecanismos de manipulação que permitem efectuar a transferência de informação
entre processos.
(MITCHELL Mark; et. al. (2001), definem simplesmente como sendo a transferência de
dados entre processos.
3.1. TIPOS DE IPC
3.1.1. PIPES
3.1.2. FILAS DE MENSAGENS
3.1.3. MEMÓRIA PARTILHADA
Tabela 1 – A árvore de directorias do Linux (PEREIRA Paulo, 2005)
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 17
3.2. SINCRONIZAÇÃO ENTRE PROCESSOS
3.2.1. SINAIS
3.2.2. SEMÁFOROS
3.3. A CORREÇÃO DOS PROGRAMAS
Este subcapítulo faz parte do primeiro trabalho prático da disciplina de Tecnologías e
Sistemas da computação, de maneira a praticar-se e de forma mais direrecta e
perceber os conceitos sobre os IPC. Além de fazer-se a correção dos programas, o
grande objectivo será o estudo e as suas interpretações.
3.3.1. O PROGRAMA SOBRE PIPES
VARIÁVEIS DECLARADAS 3.3.1.1.
Essencial descrever exactamente este trecho, para se ter noção das intenções do
programa.
No acto de criação de um Pipe, é essencial pensar na declaração de seus estremos.
Como podemos ver, para um Pipe, este será sempre um array inteiro de dimensão 2
denominado como array dos file descriptor (descritores de ficheiro) devido a sua
utilidade. Quando se cria um Pipe, O sistema retorna os dois descritores que
representam o lado de escrita e o lado de leitura.
Na condição a seguir, começa-se por aplicar uma regra muito importante dos Pipes,
quando é que deve-se fechar o lado receptor, e quando é que deve-se fechar o lado
emisso, de maneiras a haver a comunicação sem erro algum. Para este caso, quando
int fd[2]; /* Declaração da variável "file descriptor", irá armazenar os serviços de escrita e leitura */ char b_entr[BUFSIZ]; /* Declaração da variavel para Alocação estática do buffer de memória*/ pid_t childpid; /* Declaração da variável que armazena o ID do Processo Filho*/ pipe(fd); /* Função Pipe com paramentro que retorna fd (0) e fd(1), que são 2 inteiros */
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 18
o processo for filho, este irá fechar o lado receptor do Pipe e simplesmente poder
escrever.
Contrariamente, caso o processo for pai, este irá fechar o lado emissor do Pipe e
simplesmente permitir a sua leitura, também de maneiras a permitir a continuidade da
comunicação.
3.3.2. O PROGRAMA SOBRE FILAS DE MENSAGENS
/* Na condição a seguir é testado a condição de criação do processo filho, caso concretizar-se é inicializada a função fd com parametro 0 */ if((childpid = fork()) == 0) { close (fd[0]); /* O índice 0 fecha o lado receptor do Pipe */ printf("Eu sou o processo Filho!\n"); dup(fd[0]); /*Duplica o file descriptor de entrada da pipe (fd(0)) na sua entrada padrão */ execlp ( "ps","-al",0); /*Sobrepor o código do processo filho com o do comando "ps" */ close (fd[1]); exit(0); }
/* Execução do processo pai */ else { /* Esta função serve para forçar uma paragem na execução do processo pai até que o processo filho termine a sua execução*/ wait (0); close (fd[1]); /* O índice 1 Fecha o lado emissor do Pipe */ printf("Eu sou o processo pai! \n"); /* Condição de fazer a leitura do file descriptor fd(0) e saber o tamanho do buffer através do ponteiro &b_entr */ while (read(fd[0],&b_entr,BUFSIZ)) printf("%s",b_entr); /* Imprimir o tamanho do buffer no ecrã */ close(fd[0]); exit(0);
}
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 19
VARIÁVEIS DECLARADAS 3.3.2.1.
Quanto as variáveis, é importante perceber que temos uma variável do tipo struct que
irá armazenar o tipo de mensagem e a própria mensagem. Logo a seguir temos o
identificador da nossa mensagem que é um valor inteiro e temos a string a ser
enviada.
Nesta secção seguinte, é importante ter a função ftok(), como o processo para a
criação da chave da mensagem.
A função msgget permite criar ou obter o acesso a uma fila de mensagem, o retorno
do valor -1 não havendo a criação do identificador da mensagem o programa retorna
em erro Obrigatoriamente a mensagem deve ter um identificado de maneira a permitir
a sua comunicação com outros processos.
A função msgsnd(), permite enviar uma mensagem a estrutura de fila de mensagem já
criada. Caso haver algum erro de envio, o valor a ser retornado será -1.
E por último iremos simplesmente exibir a mensagem enviada, atravês de uma
estrutura denominada de Fila de mensagem.
key_t chv_f_msg; /* Declaração da variável do tipo key_t usada para obter o ID do objecto IPC (Clente ou Servidor)*/ /* Criação da variável (message buffer) do tipo struct que armazena as variáveis "tipo de mensagem e a mensagem propriamente dita" */ struct mi_m { long tipo; char texto[251]; } mensagem; /* ID da fila de mensagem */ int num_f_msg; /* Cadeia de caracteres com a mensagem para ser enviada */
char string[] = "\n Mantenha a informação livre!\n";
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 20
3.3.3. SINAIS
/* Copiar a string para o referido destino */ mensagem.tipo=1; strcpy(mensagem.texto,string); /* Função usada para gerar valores das chaves (ID) tanto do cliente como do servidor que correm no directorio actual (em execução) */ chv_f_msg = ftok(".", 'a'); /* A Função msgget() serve para criar ou obter o ID da fila de mensagem.*/ if ((num_f_msg = msgget(chv_f_msg,IPC_CREAT | 0660 ))==-1) /* Retorna -1 em caso de erro, caso não, retorna o identificador da fila de mensagens*/ { perror( "Erro na abertura da fila de mensagens" ); exit(-1); } /* A Função msgsnd() serve para enviar uma mensagem à fila de mensagens já criada. */ if (msgsnd(num_f_msg,&mensagem,255,IPC_NOWAIT)==-1) /* Retorna -1 em caso de erro, caso não, envia a mensagem na fila de mensagem */ { perror( "Erro no envio da mensagem" ); exit(-1); } printf(" %s \n", mensagem.texto); /*Imprime a mensagem no ecrã*/
}
/* Cópia da definição da estrutura 'sigaction', presente na header file 'signal.h', que examina e muda a acção de um sinal*/ struct sigaction act; /* Função de manipulação de possíveis sinais recebidos*/
void sighandler(int signum, siginfo_t *info, void *ptr)
/* Instrução que escreve o número e a origem de sinais recebidos*/ printf("Received signal %d\n", signum); printf("Signal originates from process %lu\n", (unsigned long)info->si_pid); } /* Função principal, onde o programa inicia a execução. */ int main() { /* Instrução que escreve o pid do processo corrente na tela */ printf("I am %lu\n", (unsigned long)getpid()); /* Definição dos princípios de utilização dos sinais */ memset(&act, 0, sizeof(act)); act.sa_sigaction = sighandler; act.sa_flags = SA_SIGINFO; sigaction(SIGTERM, &act, NULL); /* Função que inicia a espera por CTRL+C... */ sleep(100);
/* Retorno da função main() */ return 0;
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 21
3.3.4. SOCKETPAIR
VARIÁVEIS DECLARADAS 3.3.4.1.
Neste programa foram declarados, um array de dois inteiros que irá armazenzar o par
de sockets, dois ponteiros que irão permitir que sejam apontados no acto de
visualização de suas mensagens. E as Strings a serem armazenadas em
determinadas localizações.
Logo a seguir, tal como está o comentário, achei preferível ordenar o trabalho de
modos a que o processo filho irá fazer a escrita da string na memória e o processo pai
ira efectuar a leitura atravês de ponteiros.
Com mais detalhe, é visto que no acto de criação atravês do fork, o processo filho é
preparado para escrever uma cadeia de 27 caracteres, enquanto que o processo pai é
preparado para fazer a leitura dessa cadeia.
int s[2];
void *ptrc_0,*ptrc_1; /* Declaração de dois ponteiros */
char cadeia_0[] = "Mantenha a informação livre!\n"; /* Declaração de uma String
* /
char cadeia_1[] = "ervil informação a ahnetnaM!\n"; /* Declaração de uma String
*/
ptrc_0=malloc(128); /* Alocação dinâmica de memória */
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 22
3.4. O PROGRAMA DA MEMÓRIA PARTILHADA
Neste programa trabalhei com 4 ficheiros importantes:
Makefile: Como estudado, o makefile permite automatizar o processo de
criação dos programas objectos. Mas para tal é necessário obedecer a regras
de dependencia entre o objecto a ser criado e os devidos códigos fontes como
vimos no código a seguir trabalhado:
/* Nas condições seguintes: O processo filho irá escrever a cadeia as cadeias de
27 caracteres e o processo pai irá ler o que o processo filho escreveu atravês do
endereço de memória */
if (fork()== 0)
{ write (s[0],cadeia_0,27);
write (s[1],cadeia_1,27);
printf("\n\n O Processo filho escreve nos endereço:\n %p e %p",ptrc_0,
ptrc_1);
}
else
{ read (s[0],ptrc_0,27);
read (s[1],ptrc_1,27);
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 23
memm.c: Este é o programa principal da nossa memória partilhada.
Este ficheiro descreve a funcionalidade e o objectivo principal do trabalho. O processo
pai escreve os números inteiros de 1 a 20, enquanto que o filho faz a leitura e imprime
no ecrâ.
Neste programa, foi implementado uma memória partilhada com o auxílio de
semáforo.
A função a seguir (ShmDef), reserva uma zona de memória partilhada, com o tamanho
suficiente para armazenar um array de 20 inteiros.
Top:= $(Shell Pdw)
semaforo: memm.c
g++ -ansi -pedantic -Wall -o memoria memm.c $(Top)
semlib.o : semlib.c
g++ -ansi -pedantic -Wall -c semlib.c
shmlib.o : shmlib.c
g++ -ansi -pedantic -Wall -c shmlib.c
install:
mv semaforo..
apt = (int *) ShmDef(sizeof(int)*20, &shmd);
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 24
As condições neste trabalho estão devidamente descritas e em anexo. Por uma
questão de uma boa apresentação, foi preferível descrever de forma síntetica a forma
geral do processo.
semlib.c: Biblioteca do semáforo
Este ficheiro contém um conjunto de de funções que possibilitam operar com os
mecanismos de semáforos existentes em Linux.
A Função SemDef(), permite definir um semáforo no kernel, privado a um determinado
processo e os seus filhos.
A função SemSignal() é o descritor que permite incrementar o valor do semáforo.
A função SemWait() implementa o Wait que permite decrementar o valor do
semáforo.
A Função SemDel(), Permite disponibilizar os recursos que são ocupados pelo
semáforo no sistema operativo.
shmlib.c: Biblioteca da memória partilhada. Esta é constituida por duas
funções: ShmDef () e ShmDel(). A primeira função serve para a obtenção de
uma zona de partilhada enquanto que a segunda permite tornar disponivel uma
zona de memória partilhada privada.
O size define o comprimento da zona memoria partilhada. O descr identifica perante o Kernel a zona de memoria partilhada que foi criada.
void *ShmDef(int size, int *descr)
int ShmDel(int descr)
int SemDef( int inicial_value); int SemSignal(int descr_sem); int SemWait( int descr_sem);
int SemDel( int descr_sem);
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 25
4. CONCLUSÃO
Este trabalho permitiu ter a noção geral sobre processos em Linux. Permitiu receber
uma grande incentivação de maneira a continuar com as pesquisas e estar bem
preparado para próximos testes a surgirem.
Verifiquei que para um ambiente acadêmico o Linux torna-se como um grande suporte
no ensino sobre sistemas operativos, por permitir efectuar testes reais sobre suas
funções.
Permitiu também ter a noção real sobre o Linux como um sistema operativo bastante
seguro, e ter contacto prático sobre o seu desenvolvimento como um programador
pertencente a sua comunidade.
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 26
REFERÊNCIAS
PEREIRA, Pereira (2005) – Linux – Curso completo. 5ª ed. Lisboa: FCA Editora.
MITCHELL, Mark; et. al. (2001) – Advanced Linux Programming 1ª ed. Indiana: New
Riders.
CRESPO, Rui (2001) – Processadores de linguagens – Da Concepção à
implementação. 2ª ed. Lisboa: IST Press.
KOWALTOWSKI, Tomasz (2010) – Estrutura de dados e técnicas de programação
[Em linha]. [Consult. 06 Mai. 2012]. Disponível em
WWW:<http://colibri.ic.unicamp.br/~tomasz/cursos/mc202/transp_ho_acum.pdf>.
LOPES, Arthur (1999) – Estrutura de dados – Para a construção de softwares. 1ª Ed.
Canoas: Editora da Ulbra.
NETO, António (1998) – Explorando recursão e fractals [Em linha]. [Consult. 06 Mai.
2012].Disponível:WWW:<http://lsm.dei.uc.pt/ribie/docfiles/txt200342415342159M.PDF
>.
GUARI, Eiton (1989) – Introduction to theory of the computation. [Em linha].
[Consult.06.Mai.2012].Disponível:WWW:<http://www.cse.ohio-
state.edu/~gurari/theory-bk/theory-bk.html>.
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS (IPC)
Hercílio Rui Dinis Duarte 28
LISTA DE ANEXOS
Anexo A - Código fonte do programa principal de memória partilhada
Anexo B - Código fonte da biblioteca de memória partilhada Anexo C - Código fonte da biblioteca de semáforos Anexo D - Código do Makefile
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 29
ANEXO A Código fonte do programa principal de memória partilhada
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 30
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include "semlib.c"
#include "shmlib.c"
main(void)
{
int *apt;
int f;
int pid;
int s; /* Descritor do semáforo */
int shmd; /* Descritor da memória partilhada */
int erro;
apt = (int *) ShmDef(sizeof(int)*20, &shmd);
if (apt == NULL)
{
perror("Erro na obtenção de memoria partilhada\n");
exit(-1);
}
/* Define um semáforo com valor incial igual a 1 */
s = SemDef(1);
if (s == -1)
{
perror("Erro na criação do semáforo");
exit(-1);
}
pid = fork();
if (pid > 0)
{
/* Código do processo pai */
SemWait(s);
printf("Pai: a escrever na memória partilhada!!\n");
/* Inicio da secção crítica */
for(f=0; f < 20; f++)
{
apt[f] = f;
}
sleep(3);
printf("Pai: a sair da secção crítica\n");
/* Fim da secção crítica */
SemSignal(s);
/* Coloca o pai ‘a espera do filho */
wait();
/* Remove a zona de memória partilhada */
erro = ShmDel(shmd);
if (erro == -1)
{
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 31
printf("Pai: Erro em ShmDel!!!");
exit(-1);
}
/* Remove o semáforo */
erro = SemDel(s);
if (erro == -1)
{
printf("Pai: Erro em SemDel!!!");
exit(-1);
}
printf("Pai:Processo pai a terminar!!!\n");
}
else
{
/* Código do filho */
sleep(3);
printf("Filho: 'a espera para entrar na secção crítica!!\n");
/* Inicio da secção crítica */
SemWait(s);
printf("Filho: a executar a secção crítica\n");
for(f=0; f < 20; f++)
{
printf("Filho: f=%d val=%d\n", f, apt[f]);
sleep(1);
}
printf("Filho: a sair da secção crítica\n");
SemSignal(s);
/* Fim da secção crítica */
exit(0);
return (0);
}
}
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 32
ANEXO B Código fonte da biblioteca da memória partilhada
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 33
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <unistd.h>
#include <stdio.h>
void *ShmDef(int size, int *descr)
{
int descritor;
void *tst;
/* obtenção de um descriptor para a zona de memória partilhada */
descritor = shmget(IPC_PRIVATE, size, IPC_CREAT|0600);
if (descritor == -1)
{
perror("Erro em shmget, ao alocar memória partilhada!");
return(NULL);
}
else
{
/* Obtençao do apontador para a area de memoria partilhada */
tst = (void *) shmat(descritor, NULL, 0);
if ((int)tst == -1)
{
perror("Erro em shmat, ao alocar memória partilhada!");
return(NULL);
}
} /* fim do if */
*descr = descritor;
return(tst);
}
int ShmDel(int descr)
{
int res;
res = shmctl(descr, IPC_RMID, NULL);
if (res == -1)
{
perror("Erro em ShmDel!");
}
return(res);
}
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 34
ANEXO C
Código fonte da biblioteca de semáforo
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 35
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/sem.h>
#include <unistd.h>
#include <ctype.h>
union semun
{
int val; /* value for SETVAL */
struct semid_ds *buf; /* buffer for IPC_STAT & IPC_SET
*/
unsigned short int *array; /* array for GETALL & SETALL */
struct seminfo *__buf; /* buffer for IPC_INFO */
};
int SemDef(int valor_inicial)
{
int descr_sem;
int erro;
/* Criação do Semáforo */
descr_sem = semget(IPC_PRIVATE, 1, IPC_CREAT|0777);
if (descr_sem == -1)
{
perror("Erro ao criar o semáforo!");
return(-1);
}
/* Inicializa o valor do semáforo */
erro = semctl(descr_sem, 0, SETVAL, valor_inicial);
if (erro == -1)
{
perror("Erro ao atribuir valor inicial ao semáforo!");
return(-1);
}
return(descr_sem);
}
int SemSignal(int descr_sem)
{
struct sembuf aux;
int erro;
/* Preenche a estrutura que permite operar sobre o semáforo */
aux.sem_num = 0;
aux.sem_op = 1;
aux.sem_flg = 0;
/* Excuta a operação */
erro = semop(descr_sem, &aux, 1);
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 36
if (erro == -1)
{
perror("Erro em Signal!");
return(-1);
}
/* Em caso de sucesso da função */
return(0);
}
int SemWait(int descr_sem)
{
struct sembuf aux;
int erro;
/* Preenche a estrutura que permite operar sobre o semáforo */
aux.sem_num = 0;
aux.sem_op = -1;
aux.sem_flg = 0;
/* Excuta a operação */
erro = semop(descr_sem, &aux, 1);
if (erro == -1)
{
perror("Erro em Wait!");
return(-1);
}
/* Em caso de sucesso da função */
return(0);
}
int SemDel(int descr_sem)
{
union semun aux;
return(semctl(descr_sem, 0, IPC_RMID, aux));
}
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 37
ANEXO D
Código do Makefile
PRIMEIRO RELATÓRIO DE COMUNICAÇÃO ENTRE PROCESSOS
Hercílio Rui Dinis Duarte 38
Top:= $(Shell Pdw)
semaforo: memm.c
g++ -ansi -pedantic -Wall -o memoria memm.c $(Top)
semlib.o : semlib.c
g++ -ansi -pedantic -Wall -c semlib.c
shmlib.o : shmlib.c
g++ -ansi -pedantic -Wall -c shmlib.c
install:
mv semaforo..
clean:
rm*
top related