1. 程式人生 > >作業系統—讀者寫者問題

作業系統—讀者寫者問題

/*
 *   讀者寫者問題,讀者寫者是否公平競爭,讀優先寫優先不同
 *   讀者之間不互斥,可以多個讀操作同時進行
 *   讀操作和寫操作不可以同時進行(R-W,互斥)
 *   寫操作和寫操作不可以同時進行(W-W,互斥)
 *   在實際應用中,寫優先非常重要,因為寫代表的是對資料的更新。
 *   而我們希望讀到的是最新的訊息。因此繼續進行改進,就要考慮,
 *   如果寫者到來,可以讓正在讀的讀者讓路,先讓寫者寫。
 *   要求實現的是讀者寫者公平
 */
#include <stdio.h>
#include <ctype.h>
#include <stdlib.h>
#include <unistd.h>
#include <pthread.h>
#include <semaphore.h>
#define N 20

int readcount=0,writecount=0;
sem_t s,w;// 同步訊號量
pthread_mutex_t mutex,wmutex;

void *writer(void *a)//讀者寫者公平
{
    while(1)
    {
        sleep(1);
        pthread_mutex_lock(&wmutex);//P(wmutex);
        writecount++;
        if(writecount==1)
            sem_wait(&s);//P(S);
        pthread_mutex_unlock(&wmutex);//V(wmutex);
        sem_wait(&w);//P(w);
        printf("Writing is writing\n");//寫
        sleep(1);
        sem_post(&w);//V(w);
        pthread_mutex_lock(&wmutex);//P(wmutex);
        writecount--;
        if(writecount==0)
            sem_post(&s);//V(S);
        pthread_mutex_unlock(&wmutex);//V(wmutex);
    }
}
void *reader(void *a)//讀者寫者公平
{
    while(1)
    {
        sleep(1);
        sem_wait(&s);//P(S);
        pthread_mutex_lock(&mutex); //給互斥體變數加鎖//P(mutex);
        readcount ++;
        if(readcount==1)
            sem_wait(&w);//P (w);
        pthread_mutex_unlock(&mutex);//V(mutex); 
        sem_post(&s);  //V(S); 
        printf("Reader is reading\n");//讀
        sleep(1);
        pthread_mutex_lock(&mutex); //P(mutex);
        readcount --;
        if(readcount==0)
            sem_post(&w);//V(w);
        pthread_mutex_unlock(&mutex);//V(mutex);
    }
}

int main()
{
    int i;
    int ret[N];
    // 初始化同步訊號量
    int ini1 = sem_init(&s, 0, 1);//函式sem_init()用來初始化一個訊號量
    int ini2 = sem_init(&w, 0, 1);
    if(ini1!=0 ||ini2 != 0)
    {
        printf("sem init failed \n");
        exit(1);
    }
    //初始化互斥訊號量
    int ini3 = pthread_mutex_init(&mutex, NULL);
    int ini4 = pthread_mutex_init(&wmutex, NULL);
    if(ini3 !=0 ||ini4!=0)
    {
        printf("mutex init failed \n");
        exit(1);
    }
    pthread_t id1[N];
    pthread_t id2[N];
    for(i = 0; i < 10; i++)
    {
        pthread_create(&id2[i], NULL, reader, NULL);
    }
    for(i = 0; i < 5; i++)
    {
        ret[i] = pthread_create(&id1[i], NULL, writer, (void *)(&i));
        if(ret[i] != 0)
        {
            printf("product%d creation failed \n", i);
            exit(1);
        }
    }
    for(i = 10; i < 20; i++)
    {
        ret[i] = pthread_create(&id2[i], NULL, reader, NULL);
        if(ret[i] != 0)
        {
            printf("prochase%d creation failed \n", i);
            exit(1);
        }
    }
    for(i = 5; i < 10; i++)
    {
        ret[i] = pthread_create(&id1[i], NULL, writer, (void *)(&i));
        if(ret[i] != 0)
        {
            printf("product%d creation failed \n", i);
            exit(1);
        }
    }
    for(i = 0; i < N; i++)//銷燬執行緒
    {
        pthread_join(id1[i],NULL);
        pthread_join(id2[i],NULL);
    }
    exit(0);//還是完全沒搞清楚多執行緒怎麼在執行,鬱悶
    //執行結果有問題,不過助教還是讓過了,並講解一番,贊一個 :)
}