Difference between revisions of "Zibaldone"
Jump to navigation
Jump to search
(Aggiunta possibile soluzione) |
(Corretto typo e aggiunto spunto per l'individuazione dell'errore) |
||
Line 139: | Line 139: | ||
Propongo la seguente soluzione. Mi sembra che funzioni ma devo ancora capire perchè e documentarla bene. Ho provato prima a cercare il bug ma non ci sono riuscito. Ho quindi modificato il codice secondo ciò che mi sembrava sensato in base alle condizioni del problema. Ne possiamo parlare in aula oggi. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 12:48, 11 November 2016 (CET) | Propongo la seguente soluzione. Mi sembra che funzioni ma devo ancora capire perchè e documentarla bene. Ho provato prima a cercare il bug ma non ci sono riuscito. Ho quindi modificato il codice secondo ciò che mi sembrava sensato in base alle condizioni del problema. Ne possiamo parlare in aula oggi. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 12:48, 11 November 2016 (CET) | ||
− | + | Ho notato che l'errore non si manifesta più eliminando il controllo che ci siano scrittori in attesa quando un lettore vuole iniziare a scrivere. Non capisco come questo possa essere collegato al bug. --[[User:FedericoB|FedericoB]] ([[User talk:FedericoB|talk]]) 15:10, 11 November 2016 (CET) | |
<syntaxhighlight lang=C> | <syntaxhighlight lang=C> | ||
#include<stdio.h> | #include<stdio.h> | ||
Line 148: | Line 148: | ||
#define NUMBER_OF_READERS 3 | #define NUMBER_OF_READERS 3 | ||
#define NUMBER_OF_WRITERS 3 | #define NUMBER_OF_WRITERS 3 | ||
− | |||
− | |||
semaphore mutex; | semaphore mutex; | ||
semaphore ok2read; | semaphore ok2read; | ||
Line 155: | Line 153: | ||
int numberOfReaders=0; | int numberOfReaders=0; | ||
− | int | + | int numberOfWriters=0; |
int waitingReaders=0; | int waitingReaders=0; | ||
int waitingWriters=0; | int waitingWriters=0; | ||
Line 165: | Line 163: | ||
// <await nw == 0 -> nr++> | // <await nw == 0 -> nr++> | ||
semaphore_P(mutex); | semaphore_P(mutex); | ||
− | if ( | + | if (numberOfWriters > 0) { |
waitingReaders++; | waitingReaders++; | ||
semaphore_V(mutex); | semaphore_V(mutex); | ||
Line 172: | Line 170: | ||
} | } | ||
numberOfReaders++; | numberOfReaders++; | ||
− | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, | + | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters); |
if (waitingReaders > 0 ) | if (waitingReaders > 0 ) | ||
semaphore_V(ok2read); | semaphore_V(ok2read); | ||
Line 183: | Line 181: | ||
semaphore_P(mutex); | semaphore_P(mutex); | ||
numberOfReaders--; | numberOfReaders--; | ||
− | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, | + | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters); |
if (numberOfReaders == 0 && waitingWriters > 0) | if (numberOfReaders == 0 && waitingWriters > 0) | ||
semaphore_V(ok2write); | semaphore_V(ok2write); | ||
Line 193: | Line 191: | ||
// <await nw == 0 && nr == 0 -> nw++> | // <await nw == 0 && nr == 0 -> nw++> | ||
semaphore_P(mutex); | semaphore_P(mutex); | ||
− | if ( | + | if (numberOfWriters > 0 || numberOfReaders > 0) { |
waitingWriters++; | waitingWriters++; | ||
semaphore_V(mutex); | semaphore_V(mutex); | ||
Line 199: | Line 197: | ||
waitingWriters--; | waitingWriters--; | ||
} | } | ||
− | + | numberOfWriters++; | |
− | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, | + | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters); |
semaphore_V(mutex); | semaphore_V(mutex); | ||
} | } | ||
Line 207: | Line 205: | ||
// <nw--> | // <nw--> | ||
semaphore_P(mutex); | semaphore_P(mutex); | ||
− | + | numberOfWriters--; | |
− | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, | + | printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters); |
if (waitingReaders > 0) | if (waitingReaders > 0) | ||
semaphore_V(ok2read); | semaphore_V(ok2read); |
Revision as of 15:10, 11 November 2016
Codice ERRATO dei lettori scrittori che dovrebbe non soffrire di problemi di starvation... Esercizio: trovare gli errori.
#include<stdio.h>
#include<stdint.h>
#include<pthread.h>
#include<semaphore.h>
#define NREADER 3
#define NWRITER 3
semaphore mutex;
semaphore ok2read;
semaphore ok2write;
int nr=0;
int nw=0;
int wr=0;
int ww=0;
int w_last;
// (nw == 0 && nr == 0) || (nr > 0 && nw == 0) || nw == 1
// (nw == 0 && nr >= 0) || nw == 1
// this "baton" function has been left for reference only.
// code to implement "passing the baton" has been copied at the end of
// each ({start}|{end})({read}|{write}) function and reduced.
void baton(void) {
if (nw == 0 && nr == 0 && ww > 0)
semaphore_V(ok2write);
else if (nw == 0 && wr > 0 )
semaphore_V(ok2read);
else
semaphore_V(mutex);
}
void startread(void) {
// <await nw == 0 -> nr++>
semaphore_P(mutex);
if (nw > 0 && ww == 0) {
wr++;
semaphore_V(mutex);
semaphore_P(ok2read);
wr--;
}
nr++;
w_last=0;
printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
if (wr > 0 )
semaphore_V(ok2read);
else
semaphore_V(mutex);
}
void endread(void) {
// <nr-->
semaphore_P(mutex);
nr--;
printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
if (nr == 0 && ww > 0)
semaphore_V(ok2write);
else
semaphore_V(mutex);
}
void startwrite(void) {
// <await nw == 0 && nr == 0 -> nw++>
semaphore_P(mutex);
if (nw > 0 || nr > 0) {
ww++;
semaphore_V(mutex);
semaphore_P(ok2write);
ww--;
}
nw++;
w_last=1;
printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
semaphore_V(mutex);
}
void endwrite(void) {
// <nw-->
semaphore_P(mutex);
nw--;
printf("NR %d - NW %d - WR %d - WW %d \n", nr, nw, wr, ww);
if (wr > 0 && (ww == 0 || w_last))
semaphore_V(ok2read);
else if (ww > 0 && (wr == 0 || !w_last))
semaphore_V(ok2write);
else
semaphore_V(mutex);
}
void *reader(void *arg) {
int i = (uintptr_t)arg;
while (1) {
//other code
usleep(random() % 200000);
startread();
//read
usleep(random() % 200000);
endread();
}
}
void *writer(void *arg) {
int i = (uintptr_t)arg;
while (1) {
//other code
usleep(random() % 200000);
startwrite();
//write
usleep(random() % 200000);
endwrite();
}
}
//printf("philo thinking: %d\n",i);
/*while*/
int main(int argc, char *argv[]) {
int i;
pthread_t t;
srandom(time(NULL));
mutex=semaphore_create(1);
ok2read=semaphore_create(0);
ok2write=semaphore_create(0);
for (i=0; i<NREADER; i++)
pthread_create(&t, NULL, reader, (void *)(uintptr_t) i);
for (i=0; i<NWRITER; i++)
pthread_create(&t, NULL, writer, (void *)(uintptr_t) i);
while(1)
pause();
}
Propongo la seguente soluzione. Mi sembra che funzioni ma devo ancora capire perchè e documentarla bene. Ho provato prima a cercare il bug ma non ci sono riuscito. Ho quindi modificato il codice secondo ciò che mi sembrava sensato in base alle condizioni del problema. Ne possiamo parlare in aula oggi. --FedericoB (talk) 12:48, 11 November 2016 (CET) Ho notato che l'errore non si manifesta più eliminando il controllo che ci siano scrittori in attesa quando un lettore vuole iniziare a scrivere. Non capisco come questo possa essere collegato al bug. --FedericoB (talk) 15:10, 11 November 2016 (CET)
#include<stdio.h>
#include<stdint.h>
#include<pthread.h>
#include<semaphore.h>
#define NUMBER_OF_READERS 3
#define NUMBER_OF_WRITERS 3
semaphore mutex;
semaphore ok2read;
semaphore ok2write;
int numberOfReaders=0;
int numberOfWriters=0;
int waitingReaders=0;
int waitingWriters=0;
// (nw == 0 && nr == 0) || (nr > 0 && nw == 0) || nw == 1
// (nw == 0 && nr >= 0) || nw == 1
void startread(void) {
// <await nw == 0 -> nr++>
semaphore_P(mutex);
if (numberOfWriters > 0) {
waitingReaders++;
semaphore_V(mutex);
semaphore_P(ok2read);
waitingReaders--;
}
numberOfReaders++;
printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters);
if (waitingReaders > 0 )
semaphore_V(ok2read);
else
semaphore_V(mutex);
}
void endread(void) {
// <nr-->
semaphore_P(mutex);
numberOfReaders--;
printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters);
if (numberOfReaders == 0 && waitingWriters > 0)
semaphore_V(ok2write);
else
semaphore_V(mutex);
}
void startwrite(void) {
// <await nw == 0 && nr == 0 -> nw++>
semaphore_P(mutex);
if (numberOfWriters > 0 || numberOfReaders > 0) {
waitingWriters++;
semaphore_V(mutex);
semaphore_P(ok2write);
waitingWriters--;
}
numberOfWriters++;
printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters);
semaphore_V(mutex);
}
void endwrite(void) {
// <nw-->
semaphore_P(mutex);
numberOfWriters--;
printf("NR %d - NW %d - WR %d - WW %d \n", numberOfReaders, numberOfWriters, waitingReaders, waitingWriters);
if (waitingReaders > 0)
semaphore_V(ok2read);
else if (waitingWriters > 0)
semaphore_V(ok2write);
else
semaphore_V(mutex);
}
void *reader(void *arg) {
int i = (uintptr_t)arg;
while (1) {
//other code
usleep(random() % 200000);
startread();
//read
usleep(random() % 200000);
endread();
}
}
void *writer(void *arg) {
int i = (uintptr_t)arg;
while (1) {
//other code
usleep(random() % 200000);
startwrite();
//write
usleep(random() % 200000);
endwrite();
}
}
//printf("philo thinking: %d\n",i);
/*while*/
int main(int argc, char *argv[]) {
int i;
pthread_t t;
srandom(time(NULL));
mutex=semaphore_create(1);
ok2read=semaphore_create(0);
ok2write=semaphore_create(0);
for (i=0; i<NUMBER_OF_READERS; i++)
pthread_create(&t, NULL, reader, (void *)(uintptr_t) i);
for (i=0; i<NUMBER_OF_WRITERS; i++)
pthread_create(&t, NULL, writer, (void *)(uintptr_t) i);
while(1)
pause();
}