h4fun Posted November 25, 2007 at 10:56 AM Report Share #150168 Posted November 25, 2007 at 10:56 AM Pessoal, Estou com um problema em mãos e gostaria de obter uma ajuda vossa se possível. Necessito de criar um programa que me faça a gestão (através de semáforos) de acesso à memoria partilhada. Tenho o codigo a funcionar , mas para um produtor , consumidor.... como posso alterar o codigo para "n" produtores e "n" consumidores? Para uma mais facil compreensão, deixo o codigo a seguir: #include "sema.h" /* definicao de constantes: produtor - consumidor ______________________*/ #define N 5 /* numeros de dados guardados em simultaneo */ #define NVEZES 10 /* numero de dados produzidos */ #define SLEEPTIME 1 /* tempo de espera */ /* definicao de constantes: memoria partilhada ________________________ */ #define SHMKEY (key_t) 0x10 /* declaracao de funcoes: produtor - consumidor _______________________ */ void produz(); void consome(); void produtor(); void consumidor(); /* declaracao de variaveis globais: semaforos _________________________ */ semaphore empty, full, mutex; /* declaracao de variaveis globais: memoria partilhada _______________ */ int shmid; int *ptr; //int buf[N]; int in=0,out=0; main () { /* declaracao de variaveis locais: produtor-consumidor */ int pid; /* process ID's */ /* declaracao de variaveis locais: memoria partilhada */ char *addr; printf("\nProblema do produtor / consumidor \n"); printf(" 1 produtor para 1 consumidor \n"); /* inicializacao: semaforos */ empty = init_sem(N); /* posicoes vazias (inicio = N) */ mutex = init_sem(1); /* exclusao mutua */ full = init_sem(0); /* posicoes cheias (inicio = 0) */ /* inicializacao: memoria partilhada */ shmid = shmget(SHMKEY, 128,0777|IPC_CREAT); addr = (char*)shmat(shmid, 0, 0); ptr = (int*)addr; in = out = 0; pid = fork (); switch(pid) { case -1: /* erro no fork */ perror("Erro na chamada a funcao fork."); exit(1); break; case 0: /* processo filho */ consumidor(); exit(0); break; default: /* processo pai */ produtor(); wait(NULL); printf("\n"); /* Liberta: semaforos */ rel_sem(mutex); rel_sem(full); rel_sem(empty); /* liberta: memoria partilhada */ shmdt (addr); shmctl (shmid, IPC_RMID,NULL); } /* fim switch */ } /* fim main */ /* produtor - consumidor _______________________________________________*/ void produz() { int item; sleep(SLEEPTIME); srand ((unsigned int) time ((time_t) NULL)); item = rand () % 10; /* insere item na memoria partilhada */ *(ptr+in)= rand ()%10; printf("Produzi o item : %d\n",*(ptr+in)); // buf[in] = item; // printf(" %d produz \t%d para o endereco %d\n", getpid(), buf[in], in); in = (in + 1) % N; } void consome() { int item = 0; sleep(SLEEPTIME); /* ... vai buscar item a memoria partilhada */ item = *(ptr+out); printf("Consumi o item : %d\n",*(ptr+out)); // item = buf[out]; // printf("%d consome \t%d do endereco %d\n", getpid(), buf[out], out); out = (out + 1) % N; } void produtor() { int i; for(i = 0; i < NVEZES; i++) { P(empty); P(mutex); produz(); V(mutex); V(full); } } void consumidor() { int i; for(i = 0; i < NVEZES; i++) { P(full); P(mutex); consome(); V(mutex); V(empty); } } /* _____________________________________________________________________*/ Alguém me pode dar umas luzes?? Obrigado! Link to comment Share on other sites More sharing options...
h4fun Posted November 30, 2007 at 12:07 AM Author Report Share #151291 Posted November 30, 2007 at 12:07 AM Bom, pelos vistos ninguém me consegue ajudar.... Obrigado na mesma... Link to comment Share on other sites More sharing options...
mogers Posted November 30, 2007 at 08:34 PM Report Share #151433 Posted November 30, 2007 at 08:34 PM Se bem me lembro, o truque é inicializar o semaforo a N e não a 0 ou 1... já não me lembro bem. O meu prof falou nisso numa teórica. O site tá em baixo senão ia ver os slides... "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
petersaints Posted December 1, 2007 at 05:36 PM Report Share #151597 Posted December 1, 2007 at 05:36 PM tenho o mesmo problema... como fazer multiplos fork para criar varios filhos?? Eu consegui criando filhos dos filhos mas será essa a melhor opção? Link to comment Share on other sites More sharing options...
petersaints Posted December 1, 2007 at 05:53 PM Report Share #151599 Posted December 1, 2007 at 05:53 PM Tipo de se eu faço pid=fork(); pid=fork(); antes do switch ou do if faz-me dois consumidores e dois produtores só fazendo pid = fork (); switch(pid) { case -1: /* erro no fork */ perror("Erro na chamada a funcao fork."); exit(1); break; case 0: /* processo filho */ pid=fork(); consumidor(); exit(0); break; case 1: consumidor(); exit(0); break; é que fico com 2 consumidores e dois produtores... se puser o segundo pid=fork() for antes do switch mesmo tendo la o case 1 com consumidor ele cria-me dois de cada... o problema é que assim os filhos são criados sequencialmente em vez de todos de uma vez... isso não poderá causa problemas de sincronização?? Link to comment Share on other sites More sharing options...
mogers Posted December 1, 2007 at 11:07 PM Report Share #151654 Posted December 1, 2007 at 11:07 PM devias ir ao manual do fork ("man 2 fork" na linha de comandos). O fork cria 2 processos, no processo filho devolve 0, no processo pai devolve o process id do filho que dificilmente é "1". Ao usar um switch tens de fazer como o h4fun, "default:" ... quanto a duvida dos semaforos nao sei responder... ainda não estudei isso 😉 mas podem ver http://paginas.fe.up.pt/~jsilva/so/t_06.pdf fala aí nisso, mas não sei se ajuda muito... "What we do for ourselves dies with us. What we do for others and the world, remains and is immortal.", Albert Pine Blog pessoal : contém alguns puzzles, algoritmos e problemas para se resolver com programação. Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now