Skip to content

Instantly share code, notes, and snippets.

@LauraSuh
Created January 17, 2013 05:03
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save LauraSuh/4553796 to your computer and use it in GitHub Desktop.
Save LauraSuh/4553796 to your computer and use it in GitHub Desktop.
#include <errno.h>
#include <sys/time.h>
#include <unistd.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <sys/sem.h>
#include <time.h>
#include <stdlib.h>
#include <semaphore.h>
#include "projeto.h"
#define N 10
#define SEM_KEY 0x1234
#define SHM_KEY 0x4321
#define SEM_RANDOM_KEY 0x1235
int shm_id;
int sem_id;
queremUsar *banheiro;
int main() {
// pthread_t thread[N*2];
int i = 0, retornoH = 1, retornoM = 1, retornoC = 1, cont = 0, rand_homem =0, rand_mulher = 0, rand_crianca =0, killForks = 0;
int pidH[N], pidM[N], pidC[N];
/** Inicializando os semaforos */
banheiro->lock = (struct sembuf*)malloc(sizeof(struct sembuf));
banheiro->unlock = (struct sembuf*)malloc(sizeof(struct sembuf));
banheiro->lock[0].sem_num = 0;
banheiro->lock[0].sem_op = -1;
banheiro->lock[0].sem_flg = 0;
banheiro->unlock[0].sem_num = 0;
banheiro->unlock[0].sem_op = 1;
banheiro->unlock[0].sem_flg = 0;
banheiro->lock[1].sem_num = 1;
banheiro->lock[1].sem_op = -1;
banheiro->lock[1].sem_flg = 0;
banheiro->unlock[1].sem_num = 1;
banheiro->unlock[1].sem_op = 1;
banheiro->unlock[1].sem_flg = 0;
banheiro->lock[2].sem_num = 2;
banheiro->lock[2].sem_op = -1;
banheiro->lock[2].sem_flg = 0;
banheiro->unlock[2].sem_num = 2;
banheiro->unlock[2].sem_op = 1;
banheiro->unlock[2].sem_flg = 0;
banheiro->lock[3].sem_num = 3;
banheiro->lock[3].sem_op = -1;
banheiro->lock[3].sem_flg = 0;
banheiro->unlock[3].sem_num = 3;
banheiro->unlock[3].sem_op = 1;
banheiro->unlock[3].sem_flg = 0;
sem_id = semget( SEM_KEY, 4, IPC_CREAT | 0666 );
/** inicializando memoria compartilhada */
shm_id = shmget (SHM_KEY, sizeof(queremUsar), IPC_CREAT | 0666);
// banheiro = shmat(shm_id, NULL, 0);
banheiro->conta_homem = 0;
banheiro->conta_mulher = 0;
banheiro->conta_crianca = 0;
/**inicializando homem */
semop (sem_id, &banheiro->unlock[0], 1);
semop (sem_id, &banheiro->unlock[0], 1);
semop (sem_id, &banheiro->unlock[0], 1);
/** inicializando mulher */
semop (sem_id, &banheiro->unlock[1], 1);
semop (sem_id, &banheiro->unlock[1], 1);
/** inicializando crianca */
semop (sem_id, &banheiro->unlock[2], 1);
/** inicializando banheiro */
semop (sem_id, &banheiro->unlock[3],1);
/** inicializando processos */
for (cont = 0; cont < N; cont++ ) {
if( retornoH != 0 && retornoM != 0 && retornoC != 0 ) { //evita que os processos filhos criem mais processos.
pidH[cont] = retornoH = fork(); //cria um novo processo e atribui sua id ao vetor pidH
} else {
break;
}
}
for (cont = 0; cont < N; cont++ ) {
if( retornoH != 0 && retornoM != 0 && retornoC != 0) { //evita que os processos filhos criem mais processos.
pidM[cont] = retornoM = fork(); //cria um novo processo e atribui sua id ao vetor pidM
} else {
break;
}
}
/*
for (cont = 0; cont < N; cont++ ) {
if(retornoH != 0 && retornoM != 0 && retornoC != 0) { //evita que os processos filhos criem mais processos.
pidC[cont] = retornoC = fork(); //cria um novo processo e atribui sua id ao vetor pidC
} else {
break;
}
}
*/
/** Chamando as funcoes */
if(retornoH == 0){ //somente filhos podem chamar as funcoes
adiciona_homem();
}
else if(retornoM == 0){ //somente filhos podem chamar as funcoes
adiciona_mulher();
}
/*
else if(retornoC == 0){ //somente filhos podem chamar as funcoes
add_child();
}
*/
else {
sleep(10);
for(killForks = 0; killForks < N; killForks++) {
kill(pidH[killForks], SIGTERM);
}
for(killForks = 0; killForks < N; killForks++) {
kill(pidM[killForks], SIGTERM);
}
// for(killForks = 0; killForks < N; killForks++) {
// kill(pidC[killForks], SIGTERM);
// }
/** Removendo a area reservada a memoria compartilhada e os semaforos criados */
shmctl(shm_id, IPC_RMID, NULL);
semctl(sem_id, 0, IPC_RMID, 0);
}
}
void adiciona_mulher() {
usleep(50000);
mulher_quer_entrar();
mulher_sai();
pthread_exit();
}
void mulher_quer_entrar() {
int i;
semop (sem_id, &banheiro->lock[1], 1);
banheiro->conta_mulher += 1;
printf("Entrou MULHER, total: %d\n",banheiro->conta_mulher);
if (banheiro->conta_mulher == 1) {
for(i=0; i<3; i++){
semop (sem_id, &banheiro->lock[0], 1);
}
}
semop (sem_id, &banheiro->lock[3], 1); //a mulher que entrou no banheiro o tranca
mulher_usa_banheiro(); //a mulher usa o banheiro
semop (sem_id, &banheiro->unlock[1], 1); //a mulher libera espaco para outra
}
void mulher_sai() {
int i;
banheiro->conta_mulher -= 1;
printf("Saiu mulher, total: %d\n", banheiro->conta_mulher);
if (banheiro->conta_mulher == 0) {
printf("Banheiro vazio!\n");
for(i=0; i<4; i++){
semop (sem_id, &banheiro->unlock[0], 1);
}
}
semop (sem_id, &banheiro->unlock[3], 1);
}
void mulher_usa_banheiro() {
printf("Mulher usando!\n");
usleep(50000);
}
void adiciona_homem() {
usleep(50000);
homem_quer_entrar();
homem_sai();
pthread_exit();
}
void homem_quer_entrar() {
int i;
semop (sem_id, &banheiro->lock[0], 1);
banheiro->conta_homem += 1;
printf("Entrou HOMEM, total: %d\n", banheiro->conta_homem);
if (banheiro->conta_homem == 1) {
for(i=0; i<2; i++){
semop (sem_id, &banheiro->lock[1], 1);
}
}
semop (sem_id, &banheiro->lock[3], 1);
homem_usa_banheiro();
semop (sem_id, &banheiro->unlock[0], 1);
}
void homem_sai() {
int i;
banheiro->conta_homem -= 1;
printf("Saiu homem, total: %d\n", banheiro->conta_homem);
if (banheiro->conta_homem == 0) {
printf("Banheiro vazio!\n");
for(i=0; i<3; i++){
semop (sem_id, &banheiro->unlock[1], 1);
}
}
semop (sem_id, &banheiro->unlock[3], 1);
}
void homem_usa_banheiro() {
usleep(50000);
printf("Homem usando!\n");
}
#ifndef PROJETO_H
#define PROJETO_H
/** Header */
void mulher_quer_entrar();
void mulher_sai();
void mulher_usa_banheiro();
void adiciona_mulher();
void homem_quer_entrar();
void homem_sai();
void homem_usa_banheiro();
void adiciona_homem();
typedef struct querem_usar {
int conta_homem;
int conta_mulher;
int conta_crianca;
struct sembuf lock[4];
struct sembuf unlock[4];
} queremUsar;
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment