Buscar

semáforos, threads, fork e memória compartilhada em c

Esta é uma pré-visualização de arquivo. Entre para ver o arquivo original

/*
 Trabalho de Sistemas Operacionais
 @ Bernardo Costa
 Prof: Andre Felipe Monteiro
 
*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <pthread.h>
#include <string.h>
#include <semaphore.h>
#include <sys/types.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <unistd.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/msg.h>
#define KEY 12345 //arbitraria
#define L 54321 //arbitraria
#define MSG_SIZE_TEXT 128
#define	pid1M "pid1 terminou"
#define	pid2M "pid2 terminou"
/*-----------------------parametros para thread----------------------------------*/
typedef struct __param {
 int * a;
 int * b;
 int semid;
 int thread;
} param;
/*-----------------------Semaforo Dijkstra----------------------------------------*/
int createSem(key_t key, int initval) 
{
 int semid ;
 union semun {
 int val ;
 struct semid_ds *buf ;
 ushort array[1] ;
 } arg_ctl ;
 semid = semget( key,1,IPC_CREAT|IPC_EXCL|0666) ;
 if (semid == -1) {
 semid = semget(key,1,0666) ; 
 if (semid == -1) {
 perror("Erro semget") ;
 exit(1) ;
 }
 }
 
 arg_ctl.val = initval ;
 if (semctl(semid,0,SETVAL,arg_ctl) == -1) {
 perror("Erro semctl") ;
 exit(1) ;
 }
 return(semid) ;
}
void downSem(int semid) 
{
 struct sembuf sempar[1];
 sempar[0].sem_num = 0 ;
 sempar[0].sem_op = -1 ;
 sempar[0].sem_flg = SEM_UNDO ;
 if (semop(semid, sempar, 1) == -1)
 perror("Erro upSem") ;
}
void upSem(int semid)
{
 struct sembuf sempar[1];
 sempar[0].sem_num = 0 ;
 sempar[0].sem_op = 1 ;
 sempar[0].sem_flg = SEM_UNDO ;
 if (semop(semid, sempar, 1) == -1)
 perror("Erro downSem") ;
}
void deleteSem(int semid) 
{
 if (semctl(semid,0,IPC_RMID,0) == -1)
 perror("Erro deleteSem");
}
/*-----------------------Memoria Compartilhada-------------------------------------*/
int AllocateSharedMemory(int n){
 return shmget(IPC_PRIVATE, n, IPC_CREAT | SHM_R | SHM_W);
}
void* MapSharedMemory(int id){
 void* addr;
 addr = shmat(id, NULL, 0); 
 shmctl(id, IPC_RMID, NULL);
 return addr;
}
/*-----------------------Funcao das Threads-----------------------------------------*/
void *loopT1(void * p){
 param * t = (param *) p;
 srand( (unsigned)time(NULL) );
 int randTime;
 float randSecTime;
 randTime = 20 + (rand() % 281);
 randSecTime = randTime*1000;
 int j;
 for(j = 0; j<100;j++){
 int copia = 0;
 downSem(t->semid);
 copia = *( t->a );
 copia --;
 usleep(randSecTime);
 *( t->a ) = copia;
 *( t->b ) = *( t->b ) + 1;
 printf("\nEu sou o Thread %d \na = %d, b = %d j = %d\n",t->thread,*(t->a), *(t->b), j+1);
 upSem(t->semid);
 
 }
 printf("\nEu, a Thread %d terminei\n",t->thread);
 
}
/*-----------------------Struct parametros para funcao das Threads-----------------*/
struct Variaveis{
 int semID;
	int a ;
	int b ;
}variaveis;
/*-----------------------Struct para Troca de Mensagens----------------------------*/
struct __msgtext {
 long mtype;
 char mtext[MSG_SIZE_TEXT];
} msgtext;
/*-----------------------Main------------------------------------------------------*/
void main (){
 srand( (unsigned)time(NULL) ); 
 int randTime; 
 float randSecTime;
 pthread_t threads[2];
 int i,j, shmemID, copia = 0, flagT1, flagT2, ret;
 int *pmem;	
 pid_t pid1, pid2;
 int semID;
 int msqID;
/*-----------------------Criacao da fila para troca de mensagem------------------*/ 
	msqID = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0666); 
	if(msqID == -1){
		printf("Erro na msqID.\n");
	}
	msgtext.mtype = 1;
/*-----------------------Criacao do semaforo-------------------------------------*/
 semID = createSem(KEY,1);
/*-----------------------Criacao da memoria compartilhada------------------------*/
 shmemID = AllocateSharedMemory(sizeof(struct Variaveis));
 printf("\n\n IDda shmem = %d\n\n", shmemID);
 struct Variaveis* addr = MapSharedMemory(shmemID);
 addr->a = 300;
 addr->b = 0;
 addr->semID = semID;
 printf("\nInicial\na = %d\nb = %d\n", addr->a, addr->b);
/*-----------------------Criando filho1-------------------------------------------*/
 if ((pid1 = fork()) < 0) {
 perror("fork");
 exit(1);
 }
 //filho1
 if (pid1 == 0) {
 for(i=0;i<100;i++){
 randTime = 20 + (rand() % 281);
 randSecTime = randTime*1000;
 downSem(semID);
 	copia = addr->a;
 	copia --;
 usleep(randSecTime);
 addr->a = copia;
 addr->b = addr->b + 1;
 printf("\nEu sou o Processo %d\na = %d, b = %d i = %d\n", getpid(), addr->a, addr->b, i+1);
 upSem(semID);
 }
 sprintf(msgtext.mtext, pid1M);
		msgsnd(msqID, &msgtext, strlen(msgtext.mtext), IPC_NOWAIT);
 }
/*-----------------------Criando filho2 dentro do PAI-------------------------------*/
 else{
 if ((pid2 = fork()) < 0) {
 perror("fork");
 exit(1);
 }
 //filho2
 if (pid2 == 0) {
/*-----------------------Encapsulando valores para ser paremetros paras as Threads--*/
 param p1;
 param p2;
 
		 downSem(semID);
 p1.a = &addr->a;
 p1.b = &addr->b;
 p1.semid = semID; 
 p1.thread = 1;
 upSem(semID);
 
 downSem(semID);
 p2.a = &addr->a;
 p2.b = &addr->b;
 p2.semid = semID; 
 p2.thread = 2;
 upSem(semID);
/*-----------------------Criando as Threads-----------------------------------------*/
 flagT1 = pthread_create(&threads[0], NULL, loopT1, (void *)&p1);
 if (flagT1!=0) printf("Erro na criação da thread1\n");
 
 flagT2 = pthread_create(&threads[1], NULL, loopT1, (void *)&p2);
 if (flagT2!=0) printf("Erro na criação da thread2\n");
 pthread_join( threads[0], NULL );
 pthread_join( threads[1], NULL );
 printf("\nTerminou as Threads_______________\na = %d, b = %d\n", addr->a, addr->b );
				sprintf(msgtext.mtext, pid2M);
				msgsnd(msqID, &msgtext, strlen(msgtext.mtext), IPC_NOWAIT);
 } 
/*-----------------------Pai aguarda os filhos terminarem e encerra0-----------------*/
 else { 
 	for(i=0;i<2;i++){
 ret=msgrcv(msqID,&msgtext,MSG_SIZE_TEXT,msgtext.mtype,MSG_NOERROR);
		 printf("**** Troca de Mensagem: %s**** \n", msgtext.mtext) ;
		 }
		 printf("\n\nTerminando\nResultado final\na = %d, b = %d\n", addr->a, addr->b );
 }
 }
}

Teste o Premium para desbloquear

Aproveite todos os benefícios por 3 dias sem pagar! 😉
Já tem cadastro?

Continue navegando