## Wednesday, March 12, 2014

### Readers–writers problem--Concurrency--Using Mutex

Implement Readers Writer Problem using Semaphores.

Theory:
http://en.wikipedia.org/wiki/Readers%E2%80%93writers_problem

Solution to First Reader Writer Problem --Readers preference
----------------------------------------------------------------
//no reader shall be kept waiting if the share is currently opened for reading

#include<stdio.h>
#include<pthread.h>
#include<semaphore.h>

sem_t mutex,writeblock;
int data = 0,rcount = 0;

void *reader(void *arg)
{
int f;
f = ((int)arg);
sem_wait(&mutex);
rcount = rcount + 1;
if(rcount==1)
sem_wait(&writeblock);
sem_post(&mutex);
printf("Data read by the reader%d is %d\n",f,data);
sleep(1);
sem_wait(&mutex);
rcount = rcount - 1;
if(rcount==0)
sem_post(&writeblock);
sem_post(&mutex);
}

void *writer(void *arg)
{
int f;
f = ((int) arg);
sem_wait(&writeblock);
data++;
printf("Data writen by the writer%d is %d\n",f,data);
sleep(1);
sem_post(&writeblock);
}

main()
{
int i,b;
pthread_t rtid[5],wtid[5];
sem_init(&mutex,0,1);
sem_init(&writeblock,0,1);
for(i=0;i<=2;i++)
{
pthread_create(&wtid[i],NULL,writer,(void *)i);
pthread_create(&rtid[i],NULL,reader,(void *)i);
}
for(i=0;i<=2;i++)
{
pthread_join(wtid[i],NULL);
pthread_join(rtid[i],NULL);
}
}

Solution to 2nd Reader Writer Problem [ Writer's preference ]
----------------------------------------------------------------------------------------
//no writer, once added to the queue, shall be kept waiting longer than absolutely necessary
`#include <pthread.h>`
`#include <sched.h>`
`#include <semaphore.h>`
`#include <stdio.h>`
`#include <unistd.h>`
`#define MAXTHREAD 10  /* define # readers */`
`void` `access_database();     ``/* prototypes */`
`void` `non_access_database(); `
`void``* reader(``void``*);`
`void``* writer(``void``*);`
`sem_t q;        ``/* establish que */`
`int` `rc = 0;     ``/* number of processes reading or wanting to */`
`int` `wc = 0;`
`int` `write_request = 0;`
`int` `main()`
`{`
`    ``pthread_t readers[MAXTHREAD],writerTh;`
`    ``int` `index;`
`    ``int` `ids[MAXTHREAD]; ``/* readers and initialize mutex, q and db-set them to 1 */`
`    ``sem_init (&q,0,1);`
`    ``for``(index = 0; index < MAXTHREAD; index ++)  `
`    ``{`
`        ``ids[index]=index+1;                             ``/* create readers and error check */`
`        ``if``(pthread_create(&readers[index],0,reader,&ids[index])!=0){`
`            ``perror``(``"Cannot create reader!"``);`
`            ``exit``(1);                            `
`        ``}`
`    ``}`
`    ``if``(pthread_create(&writerTh,0,writer,0)!=0){`
`        ``perror``(``"Cannot create writer"``);     ``/* create writers and error check */`
`        ``exit``(1);`
`    ``}`
`    ``pthread_join(writerTh,0);   `
`    ``sem_destroy (&q);`
`    ``return` `0;`
`}`
`void``* reader(``void``*arg)          ``/* readers function to read */`
`{`
`    ``int` `index = *(``int``*)arg;`
`    ``int` `can_read;`
`    ``while``(1){`
`        ``can_read = 1;`
`        ``sem_wait(&q);`
`        ``if``(wc == 0 && write_request == 0)  rc++;`
`        ``else`                               `can_read = 0;`
`        ``sem_post(&q);`
`        ``if``(can_read) {`
`            ``access_database();`
`            ``printf``(``"Thread %d reading\n"``, index);`
`            ``sleep(index);`
`            ``sem_wait(&q);`
`            ``rc--;`
`            ``sem_post(&q);`
`        ``}`
`        ``sched_yield();`
`    ``}`
`    ``return` `0;`
`}`
`;`
`void``* writer(``void``*arg)      ``/* writer's function to write */`
`{`
`    ``int` `can_write;`
`    ``while``(1){`
`        ``can_write = 1;`
`        ``non_access_database();`
`        ``sem_wait (&q);`
`        ``if``(rc == 0)   wc++;`
`        ``else`          `{ can_write = 0; write_request = 1; }`
`        ``sem_post(&q);`
`        ``if``(can_write) {`
`            ``access_database();  `
`            ``printf``(``"Writer is now writing...Number of readers: %d\n"``,rc);`
`            ``sleep(3);`
`            ``sem_wait(&q);`
`            ``wc--;`
`            ``write_request = 0;`
`            ``sem_post(&q);`
`        ``}`
`        ``sched_yield();`
`    ``}`
`    ``return` `0;`
`}`
`void` `access_database()`
`{`
`}`
`void` `non_access_database()`
`{`
`}`