Thread: reader/writer problem using semaphores

  1. #1
    Registered User
    Join Date
    Mar 2008
    Posts
    17

    reader/writer problem using semaphores

    I am working on writting 2 programs, the first was using the algorithm provided to me which basically blocks the writter out as long as there are readers. That wasn't much of a problem. I then wanted to change it to allow the writter to gain access without changing the delay of the current algorithm so I creating a semaphore q basically like a que to allow the writter in and it seems to work however I'm a little confused on what I did and was hoping someone could help me- I believe I created q to allow the writter in after all readers are done reading but every now and then it will let the writter in while there is still a reader and I thought by gaining exclusive access it shouldn't. Anyways if you don't mind taking a look at my code and any suggestions would be helpful. keep in mind the only thing I added from my original was sem q
    Code:
    #include <pthread.h>
    #include <semaphore.h>
    #include <stdio.h>
    #include <unistd.h>
    
    #define MAXTHREAD 4  /* define # readers */
    
    
    void access_database();		/* prototypes */
    void non_access_database();	
    
    void* reader(void*);
    void* writer(void*);
    
    sem_t mutex;	/* controls access to rc */
    sem_t db;	/* controls access to db */
    sem_t q;		/* establish que */
    int rc = 0;		/* number of processes reading or wanting to */
    int main()
    {
        pthread_t readers[MAXTHREAD],writerTh;
        int index;
        int ids[MAXTHREAD];	e readers and initialize mutex, q and db-set them to 1 */
        sem_init(&mutex,0,1);
        sem_init(&db,0,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(&mutex);
        sem_destroy(&db);
    	sem_destroy (&q);
        return 0;
    }
    
    void* reader(void*arg)			/* readers function to read */
    {
        int index = *(int*)arg;
        while(1){
    	sem_wait(&q);
    	sem_wait(&mutex);
    	rc++;
    	if(rc == 1) sem_wait(&db);
    	sem_post(&mutex);
    	
    	access_database();
    	sem_post (&q);
        printf("Thread %d reading\n",index);
    	sleep(index);
    	sem_wait(&mutex);
    	rc--;
    	if(rc == 0) sem_post(&db);
    	sem_post(&mutex);	
    	non_access_database();
    	    }
        return 0;
    }
    ;
    void* writer(void*arg)		/* writer's function to write */
    {
        while(1){
    	non_access_database();
    	sem_wait (&q);
    	sem_wait(&db);
    	
    	access_database();	
    	sem_post (&q);
    	printf("Writer is now writing...Number of readers: %d\n",rc);
    	sleep(1);
    	sem_post(&db);
        }
        return 0;
    }
    
    void access_database()
    {
    
    }
    
    
    void non_access_database()
    {

  2. #2
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    I haven't been able to find the issue with this code. It works fine for me (though under Cygwin).

    Here's a version that uses one semaphore (I think it's a little bit easier to analyze):

    Code:
    #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()
    {
    
    }

  3. #3
    Registered User
    Join Date
    Mar 2008
    Posts
    17

    Question

    I understand my code works. That isn't the problem. I guess I was just wondering why with my code does the reader still have access when the writter is writing sometimes it will say # of readers 1. I thought once the writter got access the reader was out. As far as writting using 3 semaphores that is the way the algorithm was given to us. I agree your is alot easier to understand. Before creating &q I just had &db and &mutex but it starved the writter so I was wondering when I created &q the way its written is it creating a que of some sort to enable the writter in because the writter gains access.

  4. #4
    Registered User
    Join Date
    Jan 2009
    Posts
    31
    Quote Originally Posted by jalex39 View Post
    I understand my code works. That isn't the problem. I guess I was just wondering why with my code does the reader still have access when the writter is writing sometimes it will say # of readers 1. I thought once the writter got access the reader was out. As far as writting using 3 semaphores that is the way the algorithm was given to us. I agree your is alot easier to understand. Before creating &q I just had &db and &mutex but it starved the writter so I was wondering when I created &q the way its written is it creating a que of some sort to enable the writter in because the writter gains access.
    That's what I meant by "it works". I was unable to get the program to print out anything other than zero for the number of reads in progress from the write thread (under Cygwin though).

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. Someone having same problem with Code Block?
    By ofayto in forum C++ Programming
    Replies: 1
    Last Post: 07-12-2007, 08:38 AM
  2. A question related to strcmp
    By meili100 in forum C++ Programming
    Replies: 6
    Last Post: 07-07-2007, 02:51 PM
  3. Problem with POSIX semaphores
    By kaseo88 in forum C Programming
    Replies: 7
    Last Post: 06-29-2007, 12:31 PM
  4. Semaphores Problems
    By mhelal in forum Linux Programming
    Replies: 2
    Last Post: 05-06-2007, 10:36 PM
  5. WS_POPUP, continuation of old problem
    By blurrymadness in forum Windows Programming
    Replies: 1
    Last Post: 04-20-2007, 06:54 PM