讀寫鎖


 1、概述

  讀寫鎖與互斥量類似,不過讀寫鎖允許更高的並行性。互斥量要么是鎖住狀態,要么是不加鎖狀態,而且一次只有一個線程對其加鎖。讀寫鎖可以有三種狀態:讀模式下加鎖狀態,寫模式下加鎖狀態,不加鎖狀態。一次只有一個線程可以占有寫模式的讀寫鎖,但是多個線程可用同時占有讀模式的讀寫鎖。讀寫鎖也叫做共享-獨占鎖,當讀寫鎖以讀模式鎖住時,它是以共享模式鎖住的,當它以寫模式鎖住時,它是以獨占模式鎖住的。

2、讀寫鎖API

  讀寫鎖的數據類型為pthread_rwlock_t。如果這個類型的某個變量是靜態分配的,那么可通過給它賦常值PTHREAD_RWLOCK_INITIALIZER來初始化它。

獲取和釋放讀寫鎖:
int pthread_rwlock_rdlock(pthread_rwlock_t *rwptr); //獲取一個讀出鎖
int pthread_rwlock_wrlock(pthread_rwlock_t *rwptr); //獲取一個寫入鎖
int pthread_rwlock_unlock(pthread_rwlock_t *rwptr); //釋放一個寫入鎖或者讀出鎖
都返回:成功時為0,出錯時為正的Exxx值
int pthread_rwlock_tryrdlock(pthread_rwlock_t *rwptr);
int pthread_rwlock_trywrlock(pthread_rwlock_t *rwptr);
都返回:成功時為0,出錯時為正的Exxx值

讀寫鎖屬性:
int pthread_rwlock_init(pthread_rwlock_t *rwptr, const pthread_rwlockattr_t *attr)
int pthread_rwlock_destroy(pthread_rwlock_t *rwptr);
都返回:成功時為0,出錯時為正的Exxx值

int pthread_rwlockattr_init(pthread_rwlockattr_t *attr);
int pthread_rwlockattr_destroy(pthread_rwlockattr_t *attr);
都返回:成功時為0,出錯時為正的Exxx值

int pthread_rwlockattr_getpshared(const pthread_rwlockattr_t *attr, int *valptr);
int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *attr, int valptr);
都返回:成功時為0,出錯時為正的Exxx值

讀寫鎖在不同進程間共享:
PTHREAD_PROCESS_SHARED

線程取消
通過由對方調用函數pthread_cancel,一個線程可以被同一個進程內的任何其他線程所取消(cancel):
int pthread_cancel(pthread_t tid);
都返回:成功時為0,出錯時為正的Exxx值

為處理被取消的可能情況,任何線程可以安裝(壓入)和刪除(彈出)清理處理程序:
void pthread_cleanup_push(void (*function)(void *), void *arg);
void pthread_cleanup_pop(int execute);
這些處理程序就是發生以下情況時被調用的函數:
1. 調用線程被取消(有某個線程調用pthread_cancel完成)
2. 調用線程自願終止(或者通過調用pthread_exit,或者從自己的線程起始函數返回)

寫個程序實現讀者-寫者問題,程序如下:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>
#include <pthread.h>
#include <errno.h>

#define MAXDATA     1024
#define MAXREDER    100
#define MAXWRITER   100
struct
{
    pthread_rwlock_t   rwlock;   //讀寫鎖
    char datas[MAXDATA];          //共享數據域
}shared = {
    PTHREAD_RWLOCK_INITIALIZER
};

void *reader(void *arg);
void *writer(void *arg);

int main(int argc,char *argv[])
{
    int i,readercount,writercount;
    pthread_t tid_reader[MAXREDER],tid_writer[MAXWRITER];
    if(argc != 3)
    {
        printf("usage : <reader_writer> #<readercount> #<writercount>\n");
        exit(0);
    }
    readercount = atoi(argv[1]);  //讀者個數
    writercount = atoi(argv[2]);   //寫者個數
    pthread_setconcurrency(readercount+writercount);
    for(i=0;i<writercount;++i)
        pthread_create(&tid_writer[i],NULL,writer,NULL);
    sleep(1); //等待寫者先執行
    for(i=0;i<readercount;++i)
        pthread_create(&tid_reader[i],NULL,reader,NULL);
    //等待線程終止
    for(i=0;i<writercount;++i)
        pthread_join(tid_writer[i],NULL);
    for(i=0;i<readercount;++i)
        pthread_join(tid_reader[i],NULL);
    exit(0);
}
void *reader(void *arg)
{
    pthread_rwlock_rdlock(&shared.rwlock);  //獲取讀出鎖
    printf("Reader begins read message.\n");
    printf("Read message is: %s\n",shared.datas);
    pthread_rwlock_unlock(&shared.rwlock);  //釋放鎖
    return NULL;
}

void *writer(void *arg)
{
    char datas[MAXDATA];
    pthread_rwlock_wrlock(&shared.rwlock);  //獲取寫如鎖
    printf("Writers begings write message.\n");
    printf("Enter the write message: \n");
    gets(datas);   //寫入數據
    strcat(shared.datas,datas);
    pthread_rwlock_unlock(&shared.rwlock);  //釋放鎖
    return NULL;
}

程序執行結果如下所示:


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM