|
|
|
![]() |
|
Strumenti |
![]() |
#1 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
problema dei 5 giocatori in C
Ciao,
sto cercando di risolvere il seguente problema in C ... " Si realizzi mediante thread e sincronizzazione con semafori un processo che simula 5 giocatori, seduti ad un tavolo circolare, che giocano a carte. Si supponga a questo proposito di avere un mazzo di 40 carte, la cui estrazione sia ottenuta per mezzo di un generatore pseudocasuale. Il gioco consiste nell'assegnare, durante la prima mano, una carta a testa per giocatore da porre alla sua destra. Un giocatore per poter giocare la sua mano deve poter disporre di entrambe le carte, alla sua destra e alla sua sinistra (quest'ultima assegnata al giocatore sinistro). Se sono disponibili le preleva (per cui non possono essere utilizzate contemporaneamente dai giocatori che gli stanno accanto) e, quindi, estraendo una carta dal mazzo ne fa la somma (modulo 40) con le due carte prelevate ai suoi lati e le ripone sul tavolo. Si simuli la partita per un certo numero di mani. " Il problema è molto simile a quello dei 5 filosofi, e su questo problema mi sono basato per trovare una soluzione, ma il programma non funziona ancora. per questo lancio un SOS. quale l'errore nel listato e l'eventuale soluzione ??? (il listato è in allegato) Vi ringrazio per qualsiasi aiuto mi vogliate dare! Ciao e grazie, Paplo
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#2 |
Senior Member
Iscritto dal: Dec 1999
Messaggi: 139
|
non mi è ben chiaro il funzionamento del gioco.
__________________
Ingegnere: colui che ha molta familiarità con i modelli e molto poca con le modelle. |
![]() |
![]() |
![]() |
#3 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
cosa non capisci???
cosa devono fare i giocatori !? spero che le righe seguenti ti possano far capire ... (se ti può consolare, neanche io capisco il prof! ![]() "Questo esempio è una variante del problema dei cinque filosofi che, nel caso in esame, può ribattezzarsi nel problema dei cinque giocatori. Ogni giocatore, se lo può fare, prende la propria carta e quella del vicino e le sostituisce con le loro somme successive modulo Cards essendo Cards + 1 il numero di carte del mazzo." Ciao, Paplo
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#4 |
Bannato
Iscritto dal: Jan 2001
Messaggi: 1976
|
solo in C eh ?
|
![]() |
![]() |
![]() |
#5 |
Senior Member
Iscritto dal: Dec 1999
Messaggi: 139
|
Esistono librerie fortran per scrivere programmi multiprocesso ?
__________________
Ingegnere: colui che ha molta familiarità con i modelli e molto poca con le modelle. |
![]() |
![]() |
![]() |
#6 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
L'errore che commetti e' che quando vuoi far prendere le carte al giocatore usi due wait.
In pratica il giocatore prende la prima carta , se non c'e' aspetta, quando ce l'ha prende la seconda , e se non c'e' aspetta. Di conseguenza per come l'hai impostato tu, ogni giocatore prima prende la carta alla sua destra ( ad esempio ), e poi aspetta in eterno che il suo vicino molli la propria. Cosa che non accadra' mai Quindi devi prima limitarti a controllare se la carta e' disponibile , se non lo e' rinunciare, e se invece non lo e' prenderla. Stessa cosa per la seconda. Se riesce a pescarle tutte e due gioca, altrimenti molla l'eventuale carta presa e finisce il proprio turno Non so il nome della funzione da invocare al posto di wait. Con i pthread_mutex se non sbaglio c'e' la funzione pthread_mutex_trylock(), nel tuo caso probabilmente si chiamera' trywait() |
![]() |
![]() |
![]() |
#7 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
ho indagato per trovare l'errore, e l'ho trovato ....
in pratica sbagliavo quando richiamavo LEFT e RIGHT. la giusta sintassi infatti è LEFT(i) e RIGHT(i). dopo aver risolto questo problema, ne abbiamo incontrati altri che abbiamo superato. adesso il programma restituisce qualcosa, ma qualcosa che non è esatta. infatti tutti i giocatori accedono al mazzo contemporaneamente e pescano la stessa carta. penso che il problema sia il wait come dice /\/\@®¢Ø . allego il listato modificato. vi ringrazio se potete darci un'occhiata. Ciao, Paplo.
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#8 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
bè ... l'ho allego qui ....
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#9 | |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
Quote:
non in FCA o FORTRAN !!! ![]()
__________________
Età : 28 - Sviluppatore PHP |
|
![]() |
![]() |
![]() |
#10 | |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
Quote:
Ciao e grazie, Paplo
__________________
Età : 28 - Sviluppatore PHP |
|
![]() |
![]() |
![]() |
#11 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
Ah, devono giocare per forza in un dato turno ?
Io pensavo che semplicemente chi puo' gioca e gli altri "s'attaccano" ![]() Un modo naïve può essere quello , con l'algoritmo che ti ho delineato, di continuare a provare fino a che uno non riesce a giocare: Aspetta la prima carta ( qui va bene il wait ), e cerca poi di prendere la seconda ( trywait o quel che è ): se ce la fa gioca, altrimenti rimetti giu' la carta e riprova. Il discorso fondamentale è che o prendi su entrambi le carte o le lasci giu', non puoi tenerti in mano una sola carta e aspettare che si liberi la seconda, altrimenti non si riesce a giocare. ( sempre che abbia capito correttamente il gioco of course ) |
![]() |
![]() |
![]() |
#12 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
tanto per capirsi pensavo ad una cosa simile :
void take_cards(int i) /* i= numero del filosofo, 0.. N-1 */ { bool ok=false; while( ! ok ) { if (i == 0){ wait(s[RIGHT(i)]); printf("Il giocatore %d prende la carta destra.\n", i+1); if ( trywait(s[LEFT(i)]) ) // controlla come funziona questo ! { ok = true; sleep(1); // simula una presa lenta per simulare il deadlock } else // la seconda carta non e' disponibile, rimettiamo a posto la prima e riproviamo signal( s[RIGHT(i)]); } ... in questo caso ho ipotizzato che la trywait ritorni TRUE ( non zero ) se riesce a bloccare il semaforo, FALSE altrimenti, dovresti controllare in realta' se e' cosi' o meno |
![]() |
![]() |
![]() |
#13 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
/\/\@®¢Ø, avevi capito bene prima.
questa mattina ho chiesto al prof. e in sostanza che prima arriva meglio alloggia. cmq. è più semplice far saltare il turno ad un giocatore che tenere conto dellle mani, non è vero!? cmq. nella prima soluzione che hai proposto sono superflui i semafori. ovvero è neccessario soltanto un array che memorizzi gli stati delle carte. ho inteso bene? Ciao e grazie, Paplo
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#14 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
No ! I semafori ti servono proprio per accedere a quell'array in modo sincronizzato.
Mi spiego meglio: Supponiamo che nell'array tu memorizzi 1 se la carta e' disponibile 0 altrimenti. Se memorizzi solo lo stato puo' succedere che due giocatori cerchino di prendere la stessa carta contemporaneamente o quasi, ad esempio A vede 1 e decide di prendere la carta, in quel momento la cpu passa a B che vede anche lui 1, si ritorna ad A che imposta il valore a 0 ( si prende la carta ) , e la cpu ritorna a B che fa lo stesso. Due persone con la stessa carta in mano. Se invece del contatore usi il semaforo ( che non e' altro che un contatore sincronizzato ) dopo che A "blocca" il semaforo ( la puoi considerare come una operazione "indivisibile" ) B si vede subito 0 e quindi non puo' prendersi la carta. Spero di non averti confuso le idee ancora di piu' ![]() |
![]() |
![]() |
![]() |
#15 | |
Bannato
Iscritto dal: Jan 2001
Messaggi: 1976
|
Quote:
e in Excel ? ![]() |
|
![]() |
![]() |
![]() |
#16 | |
Bannato
Iscritto dal: Jan 2001
Messaggi: 1976
|
Quote:
vedi algoritmi per la risoluzione dell'equazione di Navier-Stokes ai volumi finiti e variabili segregate. ![]() ragazzi col fortran non si gioca, si fa la guerra ! (e la pace) ![]() P.S. mi sembra poi che, in generale, chi si occupa dei linguaggi di programmazione solo per gestire funzioni di macchina e flussi di dati abbia un certo ritardo culturale, diciamo un delay puro, come le palle dei cani ![]() ![]() |
|
![]() |
![]() |
![]() |
#17 | |
Senior Member
Iscritto dal: Dec 1999
Messaggi: 139
|
Quote:
__________________
Ingegnere: colui che ha molta familiarità con i modelli e molto poca con le modelle. |
|
![]() |
![]() |
![]() |
#18 |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
Ciao,
vi chiedo un piccolo favore ancora .... mi potreste inviare o postare questi file ... pthread.h semaphore.h stdio.h stdlib.h time.h putroppo non ho installato Linux ed il compilatore per Windows non li ha a disposizione. la mia email è paplo@inwind.it Vi ringrazio molto! Ciao, Paplo
__________________
Età : 28 - Sviluppatore PHP |
![]() |
![]() |
![]() |
#19 |
Bannato
Iscritto dal: Jul 2000
Città: Malo (VI)
Messaggi: 1000
|
pthread e' specifico di una libreria e non basta copiarle l'header la devi avere tutta.
Ho trovato un port dei pthread qui , dovresti pure trovare le dll gia' precompilate. "semaphore.h" forse e' un header di linux , pero' nei pthreads ci sono pure i semafori , si tratta solo di cambiare i nomi delle funzioni. Potresti in alternativa usare le api di win32 , pero' temo che per il tuo progetto non vada bene. stdlib.h e stdio.h invece dovrebbero essere standard , strano che tu non le abbia. Se usi un compilatore C++ invece che prova a includere cstdlib e cstdio. Stessa cosa per time.h. Non so se e' standard, comunque ctime del C++ lo e'. |
![]() |
![]() |
![]() |
#20 | |
Member
Iscritto dal: Mar 2001
Città: Pordenone
Messaggi: 73
|
Quote:
Ciao e grazie, Paplo
__________________
Età : 28 - Sviluppatore PHP |
|
![]() |
![]() |
![]() |
Strumenti | |
|
|
Tutti gli orari sono GMT +1. Ora sono le: 22:24.