Skip to content

Instantly share code, notes, and snippets.

@LauraSuh
Created January 17, 2013 19:58
Show Gist options
  • Save LauraSuh/4559152 to your computer and use it in GitHub Desktop.
Save LauraSuh/4559152 to your computer and use it in GitHub Desktop.
Projeto de FSO 02/2012 erro no semaphoro linha 184 - os processos estão ignorando esse semaforo
#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 5
#define HOMEM 0
#define MULHER 1
#define CRIANCA 2
#define BANHEIRO 3
#define OCUPADO_HOMEM 4
#define OCUPADO_MULHER 5
#define SEM_KEY 0x1234
#define SHM_KEY 0x4321
#define SEM_RANDOM_KEY 0x1235
#define SEMWAIT(id, i) (semop (id, &banheiro->lock[i], 1)) /** Decrementa em um o valor do semaforo i */
#define SEMPOST(id, i) (semop (id, &banheiro->unlock[i], 1)) /** Incrementa em um o valor do semaforo i */
int shm_id;
int sem_id;
queremUsar *banheiro;
int main() {
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];
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;
/** Setando os semaforos */
banheiro->lock[HOMEM].sem_num = 0;
banheiro->lock[HOMEM].sem_op = -1;
banheiro->lock[HOMEM].sem_flg = 0;
banheiro->unlock[HOMEM].sem_num = 0;
banheiro->unlock[HOMEM].sem_op = 1;
banheiro->unlock[HOMEM].sem_flg = 0;
banheiro->lock[MULHER].sem_num = 1;
banheiro->lock[MULHER].sem_op = -1;
banheiro->lock[MULHER].sem_flg = 0;
banheiro->unlock[MULHER].sem_num = 1;
banheiro->unlock[MULHER].sem_op = 1;
banheiro->unlock[MULHER].sem_flg = 0;
banheiro->lock[CRIANCA].sem_num = 2;
banheiro->lock[CRIANCA].sem_op = -1;
banheiro->lock[CRIANCA].sem_flg = 0;
banheiro->unlock[CRIANCA].sem_num = 2;
banheiro->unlock[CRIANCA].sem_op = 1;
banheiro->unlock[CRIANCA].sem_flg = 0;
banheiro->lock[BANHEIRO].sem_num = 3;
banheiro->lock[BANHEIRO].sem_op = -1;
banheiro->lock[BANHEIRO].sem_flg = 0;
banheiro->unlock[BANHEIRO].sem_num = 3;
banheiro->unlock[BANHEIRO].sem_op = 1;
banheiro->unlock[BANHEIRO].sem_flg = 0;
banheiro->lock[OCUPADO_HOMEM].sem_num = 4;
banheiro->lock[OCUPADO_HOMEM].sem_op = -1;
banheiro->lock[OCUPADO_HOMEM].sem_flg = 0;
banheiro->unlock[OCUPADO_HOMEM].sem_num = 4;
banheiro->unlock[OCUPADO_HOMEM].sem_op = 1;
banheiro->unlock[OCUPADO_HOMEM].sem_flg = 0;
banheiro->lock[OCUPADO_MULHER].sem_num = 5;
banheiro->lock[OCUPADO_MULHER].sem_op = -1;
banheiro->lock[OCUPADO_MULHER].sem_flg = 0;
banheiro->unlock[OCUPADO_MULHER].sem_num = 5;
banheiro->unlock[OCUPADO_MULHER].sem_op = 1;
banheiro->unlock[OCUPADO_MULHER].sem_flg = 0;
/**inicializando homem */
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
/** inicializando mulher */
SEMPOST(sem_id, MULHER);
SEMPOST(sem_id, MULHER);
SEMPOST(sem_id, MULHER);
/** inicializando crianca */
SEMPOST(sem_id, CRIANCA);
SEMPOST(sem_id, CRIANCA);
/** inicializando banheiro */
SEMPOST(sem_id, BANHEIRO);
/**inicializando controle de quem entra */
SEMPOST(sem_id, OCUPADO_HOMEM);
SEMPOST(sem_id, OCUPADO_MULHER);
/** 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
adiciona_crianca();
}
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(50);
mulher_quer_entrar();
mulher_sai();
}
void mulher_quer_entrar() {
int i;
printf("###########################\n");
SEMWAIT(sem_id, OCUPADO_HOMEM);
if (banheiro->conta_homem > 0 ) {
printf("@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@\n");
SEMWAIT(sem_id, MULHER);
SEMWAIT(sem_id, MULHER);
SEMWAIT(sem_id, MULHER);
}
else{
printf("========================================");
SEMPOST(sem_id, OCUPADO_HOMEM);
}
SEMWAIT(sem_id, MULHER);
banheiro->conta_mulher += 1;
printf("Entrou MULHER, total: %d\n",banheiro->conta_mulher);
SEMWAIT(sem_id, BANHEIRO); //a mulher que entrou no banheiro o tranca
mulher_usa_banheiro();//a mulher usa o banheiro
SEMPOST(sem_id, MULHER);//a mulher libera espaco para outra pessoa
}
void mulher_sai() {
int i;
banheiro->conta_mulher -= 1;
printf("Saiu mulher, total: %d\n", banheiro->conta_mulher);
if (banheiro->conta_mulher == 0) {
printf ("\nTODAS AS MULHERES SAIRAM\n\n");
if (banheiro->conta_crianca == 0){
printf("\nBanheiro vazio!\n\n");
}
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, HOMEM);
SEMPOST(sem_id, OCUPADO_MULHER);
}
SEMPOST(sem_id, BANHEIRO);
}
void mulher_usa_banheiro() {
printf("Mulher usando!\n");
usleep(50);
}
void adiciona_homem() {
usleep(50);
homem_quer_entrar();
homem_sai();
}
void homem_quer_entrar() {
int i;
SEMWAIT(sem_id, OCUPADO_MULHER);
if (banheiro->conta_mulher > 0){
SEMWAIT(sem_id, HOMEM);
SEMWAIT(sem_id, HOMEM);
SEMWAIT(sem_id, HOMEM);
SEMWAIT(sem_id, HOMEM);
}
else{
SEMPOST(sem_id, OCUPADO_MULHER);
}
SEMWAIT(sem_id, HOMEM);
banheiro->conta_homem += 1;
printf("Entrou HOMEM, total: %d\n", banheiro->conta_homem);
SEMWAIT(sem_id, BANHEIRO);
homem_usa_banheiro();
SEMPOST(sem_id, HOMEM);
}
void homem_sai() {
int i;
banheiro->conta_homem -= 1;
printf("Saiu homem, total: %d\n", banheiro->conta_homem);
if (banheiro->conta_homem == 0) {
printf ("\nTODOS OS HOMENS SAIRAM\n\n");
if (banheiro->conta_crianca == 0){
printf("\nBanheiro vazio!\n\n");
}
SEMPOST(sem_id, MULHER);
SEMPOST(sem_id, MULHER);
SEMPOST(sem_id, MULHER);
SEMPOST(sem_id, OCUPADO_HOMEM);
}
SEMPOST(sem_id, BANHEIRO);
}
void homem_usa_banheiro() {
usleep(50);
printf("Homem usando!\n");
}
void adiciona_crianca() {
// usleep(50);
// crianca_quer_entrar();
// crianca_sai();
}
void crianca_quer_entrar(){
int i;
semop (sem_id, &banheiro->lock[CRIANCA], 1);
banheiro->conta_crianca += 1;
printf("Entrou [CRIANCA], total: %d\n", banheiro->conta_crianca);
semop (sem_id, &banheiro->lock[BANHEIRO], 1);
crianca_usa_banheiro();
semop (sem_id, &banheiro->unlock[CRIANCA], 1);
}
void crianca_sai(){
int i;
banheiro->conta_crianca -= 1;
printf("Saiu [crianca], total: %d\n", banheiro->conta_crianca);
if (banheiro->conta_homem == 0 && banheiro->conta_mulher == 0 && banheiro->conta_crianca == 0) {
printf("\nBanheiro vazio!\n\n");
}
semop (sem_id, &banheiro->unlock[BANHEIRO], 1);
}
void crianca_usa_banheiro(){
usleep(50);
printf("[Crianca] 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();
void adiciona_crianca();
void crianca_quer_entrar();
void crianca_sai();
void crianca_usa_banheiro();
typedef struct querem_usar {
int conta_homem;
int conta_mulher;
int conta_crianca;
struct sembuf lock[6];
struct sembuf unlock[6];
} queremUsar;
#endif
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment