《UNIX网络编程 卷2》读书笔记(四)

时间:2022-08-04 21:06:32
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四) /* include globals */
《UNIX网络编程 卷2》读书笔记(四)#include    
" unpipc.h "
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)
#define     MAXNITEMS         1000000
《UNIX网络编程 卷2》读书笔记(四)
#define     MAXNTHREADS            100
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* globals shared by threads */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
int         nitems;                 /* read-only by producer and consumer */
《UNIX网络编程 卷2》读书笔记(四)
int         buff[MAXNITEMS];
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
struct   {
《UNIX网络编程 卷2》读书笔记(四)  pthread_mutex_t    mutex;
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                nput;    /* next index to store */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                nval;    /* next value to store */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)}
 put  =   { PTHREAD_MUTEX_INITIALIZER } ;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
struct   {
《UNIX网络编程 卷2》读书笔记(四)  pthread_mutex_t    mutex;
《UNIX网络编程 卷2》读书笔记(四)  pthread_cond_t    cond;
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                nready;    /* number ready for consumer */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)}
 nready  =   { PTHREAD_MUTEX_INITIALIZER, PTHREAD_COND_INITIALIZER } ;
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
/* end globals */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)
void      * produce( void   * ),  * consume( void   * );
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
/* include main */
《UNIX网络编程 卷2》读书笔记(四)
int
《UNIX网络编程 卷2》读书笔记(四)main(
int  argc,  char   ** argv)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int            i, nthreads, count[MAXNTHREADS];
《UNIX网络编程 卷2》读书笔记(四)    pthread_t    tid_produce[MAXNTHREADS], tid_consume;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (argc != 3)
《UNIX网络编程 卷2》读书笔记(四)        err_quit(
"usage: prodcons6 <#items> <#threads>");
《UNIX网络编程 卷2》读书笔记(四)    nitems 
= min(atoi(argv[1]), MAXNITEMS);
《UNIX网络编程 卷2》读书笔记(四)    nthreads 
= min(atoi(argv[2]), MAXNTHREADS);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    Set_concurrency(nthreads 
+ 1);
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* 4create all producers and one consumer */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
for (i = 0; i < nthreads; i++{
《UNIX网络编程 卷2》读书笔记(四)        count[i] 
= 0;
《UNIX网络编程 卷2》读书笔记(四)        Pthread_create(
&tid_produce[i], NULL, produce, &count[i]);
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)    Pthread_create(
&tid_consume, NULL, consume, NULL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* wait for all producers and the consumer */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
for (i = 0; i < nthreads; i++{
《UNIX网络编程 卷2》读书笔记(四)        Pthread_join(tid_produce[i], NULL);
《UNIX网络编程 卷2》读书笔记(四)        printf(
"count[%d] = %d\n", i, count[i]);    
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)    Pthread_join(tid_consume, NULL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    exit(
0);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
/* end main */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
/* include prodcons */
《UNIX网络编程 卷2》读书笔记(四)
void   *
《UNIX网络编程 卷2》读书笔记(四)produce(
void   * arg)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
for ( ; ; ) {
《UNIX网络编程 卷2》读书笔记(四)        Pthread_mutex_lock(
&put.mutex);
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
if (put.nput >= nitems) {
《UNIX网络编程 卷2》读书笔记(四)            Pthread_mutex_unlock(
&put.mutex);
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)            
return(NULL);        /* array is full, we're done */
《UNIX网络编程 卷2》读书笔记(四)        }

《UNIX网络编程 卷2》读书笔记(四)        buff[put.nput] 
= put.nval;
《UNIX网络编程 卷2》读书笔记(四)        put.nput
++;
《UNIX网络编程 卷2》读书笔记(四)        put.nval
++;
《UNIX网络编程 卷2》读书笔记(四)        Pthread_mutex_unlock(
&put.mutex);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)        Pthread_mutex_lock(
&nready.mutex);
《UNIX网络编程 卷2》读书笔记(四)        
if (nready.nready == 0)
《UNIX网络编程 卷2》读书笔记(四)            Pthread_cond_signal(
&nready.cond);//发出信号
《UNIX网络编程 卷2》读书笔记(四)
        nready.nready++;//置为1 
《UNIX网络编程 卷2》读书笔记(四)
        Pthread_mutex_unlock(&nready.mutex);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)        
*((int *) arg) += 1;
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)
void   *
《UNIX网络编程 卷2》读书笔记(四)consume(
void   * arg)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        i;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
for (i = 0; i < nitems; i++{
《UNIX网络编程 卷2》读书笔记(四)        Pthread_mutex_lock(
&nready.mutex);
《UNIX网络编程 卷2》读书笔记(四)        
while (nready.nready == 0)
《UNIX网络编程 卷2》读书笔记(四)            Pthread_cond_wait(
&nready.cond, &nready.mutex);//wait条件变量
《UNIX网络编程 卷2》读书笔记(四)
        nready.nready--;//置为0
《UNIX网络编程 卷2》读书笔记(四)
        Pthread_mutex_unlock(&nready.mutex);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)        
if (buff[i] != i)
《UNIX网络编程 卷2》读书笔记(四)            printf(
"buff[%d] = %d\n", i, buff[i]);
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)    
return(NULL);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
/* end prodcons */
《UNIX网络编程 卷2》读书笔记(四)

这里在生产者的代码中,当它获取到互斥锁时,若发出信号唤醒消费者,则此时可能系统立即调度唤醒消费者,但互斥锁任然在生产者之手,则消费者获取互斥锁必然失败,为了避免此种低效的情况出现,我们可以直到生产者释放互斥锁后才给与之关联的条件变量发送信号,这在Posix里是可以这么做的,但Posix又接着说:若要可预见的调度行为,则调用pthead_cond_signal的线程必须锁住该互斥锁。

当在进程间共享互斥锁时,持有该互斥锁的进程可能在持有期间终止,但无法让系统在终止时自动释放掉所持有的锁。一个线程也可以在持有互斥锁期间终止,可能是自己调用pthread_exit或被另一个线程取消,若是前者,则它应该知道自己还有一个互斥锁,若是后者,则该线程可以先安装一个将在被取消时调用的清理处理程序。但最致命的情况是由于此线程的终止导致整个进程的终止。即使一个进程终止时系统自动释放其持有的锁,但也会导致临界区内数据处于不一致状态,

读写锁的规则:

1,只要没有线程持有某个给定的读写锁用于写,则任意数目的线程可以持有

该读写锁用于读


2
,仅当没有线程持有某个给定的读写锁用于读或用于写时,才能分配该读写锁用于写


这种锁在那些读数据比写数据频繁的应用中使用比较有用,允许多个读者提供了更高的并发度,同时在
写者修改数据时保护数据,避免任何其他读者或写者的干扰。

这种对某个给定资源的共享访问也叫共享独占上锁,获取一个读写锁用于读称为共享锁,获取一个读写锁用于写称为独占锁。在操作系统中就介绍过这种,经典的问题就是读者写者问题,有多种类型:多读者,单写者或多读者,多写者。,此外还有要考虑的就是读者和写者谁优先,也就产生了1类和2类读写问题。

      读写锁类型为pthread_rwlock_tpthread_rwlock_rdlock获取一个读出锁,若对应的读写锁已经被某个写者持有,则阻塞调用线程,pthread_rwlock_wrlock获取一个写出锁,若对应的读写锁已经被另一个写者持有或被一个或多个读者持有,则阻塞调用线程,pthread_rwlock_unlock释放一个读出锁或写入锁。

      使用互斥锁和条件变量实现读写锁(写者优先)

《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)typedef  struct   {
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  pthread_mutex_t    rw_mutex;        
/* basic lock on this struct *///访问此读写锁使用的互斥锁
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
  pthread_cond_t    rw_condreaders;    /* for reader threads waiting  读者线程使用*/
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  pthread_cond_t    rw_condwriters;    
/* for writer threads waiting  写者线程使用*/
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                rw_magic;        /* for error checking 初始化成功后, 被设置为RW_MAGIC,所有函数测试此成员,检查调用者是否作为参数传递了指向某个已经初始化的读写锁的指针,读写锁摧毁时,被设置为0*/
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                rw_nwaitreaders;/* the number waiting  读者计数器*/
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)  
int                rw_nwaitwriters;/* the number waiting   写者计数器*/
《UNIX网络编程 卷2》读书笔记(四)  
int                rw_refcount;//本读写锁的当前状态,-1表示是写入锁(任意时刻只有一个),0表示可用,大于0表示当前容纳着的读出锁数目
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
    /* 4-1 if writer has the lock, else # readers holding the lock */
《UNIX网络编程 卷2》读书笔记(四)}
 pthread_rwlock_t;
《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_init(pthread_rwlock_t  * rw, pthread_rwlockattr_t  * attr)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (attr != NULL)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);        /* not supported */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_init(&rw->rw_mutex, NULL)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
goto err1;
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_cond_init(&rw->rw_condreaders, NULL)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
goto err2;
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_cond_init(&rw->rw_condwriters, NULL)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
goto err3;
《UNIX网络编程 卷2》读书笔记(四)    rw
->rw_nwaitreaders = 0;
《UNIX网络编程 卷2》读书笔记(四)    rw
->rw_nwaitwriters = 0;
《UNIX网络编程 卷2》读书笔记(四)    rw
->rw_refcount = 0;
《UNIX网络编程 卷2》读书笔记(四)    rw
->rw_magic = RW_MAGIC;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
return(0);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)err3:
《UNIX网络编程 卷2》读书笔记(四)    pthread_cond_destroy(
&rw->rw_condreaders);
《UNIX网络编程 卷2》读书笔记(四)err2:
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_destroy(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)err1:
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
return(result);            /* an errno value */
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_destroy(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
//检查参数是否有效
《UNIX网络编程 卷2》读书笔记(四)
    if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_refcount != 0 ||
《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_nwaitreaders != 0 || rw->rw_nwaitwriters != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(EBUSY);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_destroy(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    pthread_cond_destroy(
&rw->rw_condreaders);
《UNIX网络编程 卷2》读书笔记(四)    pthread_cond_destroy(
&rw->rw_condwriters);
《UNIX网络编程 卷2》读书笔记(四)    rw
->rw_magic = 0;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
return(0);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_rdlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)    
//检查参数是否有效
《UNIX网络编程 卷2》读书笔记(四)
    if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)    
//操作读写锁前,先给其互斥锁上锁
《UNIX网络编程 卷2》读书笔记(四)
    if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* 4give preference to waiting writers */
《UNIX网络编程 卷2》读书笔记(四)    
while (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{// rw_refcount 小于0(表示有写者持有读写锁),rw_nwaitwriters大于0表示有线程正等着获取读写锁的一个写入锁,则无法获取该读写锁的一个读出锁
《UNIX网络编程 卷2》读书笔记(四)
        rw->rw_nwaitreaders++;
《UNIX网络编程 卷2》读书笔记(四)        result 
= pthread_cond_wait(&rw->rw_condreaders, &rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_nwaitreaders--;
《UNIX网络编程 卷2》读书笔记(四)        
if (result != 0)
《UNIX网络编程 卷2》读书笔记(四)            
break;
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)    
if (result == 0)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount++;        /* another reader has a read lock */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return (result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_tryrdlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_refcount < 0 || rw->rw_nwaitwriters > 0)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        result 
= EBUSY;            /* held by a writer or waiting writers */
《UNIX网络编程 卷2》读书笔记(四)    
else
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount++;        /* increment count of reader locks */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return(result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_wrlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
while (rw->rw_refcount != 0
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{//只要有读者持有读出锁或有一个写者持有唯一的写入锁,调用线程阻塞
《UNIX网络编程 卷2》读书笔记(四)
        rw->rw_nwaitwriters++;
《UNIX网络编程 卷2》读书笔记(四)        result 
= pthread_cond_wait(&rw->rw_condwriters, &rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_nwaitwriters--;
《UNIX网络编程 卷2》读书笔记(四)        
if (result != 0)
《UNIX网络编程 卷2》读书笔记(四)            
break;
《UNIX网络编程 卷2》读书笔记(四)    }

《UNIX网络编程 卷2》读书笔记(四)    
if (result == 0)
《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount = -1;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return(result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_trywrlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_refcount != 0)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        result 
= EBUSY;            /* held by either writer or reader(s) */
《UNIX网络编程 卷2》读书笔记(四)    
else
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount = -1;    /* available, indicate a writer has it */
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return(result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_unlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_refcount > 0)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount--;            /* releasing a reader */
《UNIX网络编程 卷2》读书笔记(四)    
else if (rw->rw_refcount == -1)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount = 0;        /* releasing a reader */
《UNIX网络编程 卷2》读书笔记(四)    
else
《UNIX网络编程 卷2》读书笔记(四)        err_dump(
"rw_refcount = %d", rw->rw_refcount);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* 4give preference to waiting writers over waiting readers */
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_nwaitwriters > 0{
《UNIX网络编程 卷2》读书笔记(四)        
if (rw->rw_refcount == 0)
《UNIX网络编程 卷2》读书笔记(四)            result 
= pthread_cond_signal(&rw->rw_condwriters);
《UNIX网络编程 卷2》读书笔记(四)    }
 else if (rw->rw_nwaitreaders > 0)
《UNIX网络编程 卷2》读书笔记(四)        result 
= pthread_cond_broadcast(&rw->rw_condreaders);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return(result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)int  pthread_rwlock_unlock(pthread_rwlock_t  * rw)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
{
《UNIX网络编程 卷2》读书笔记(四)    
int        result;
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_magic != RW_MAGIC)
《UNIX网络编程 卷2》读书笔记(四)        
return(EINVAL);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if ( (result = pthread_mutex_lock(&rw->rw_mutex)) != 0)
《UNIX网络编程 卷2》读书笔记(四)        
return(result);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)    
if (rw->rw_refcount > 0)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount--;            /* releasing a reader */
《UNIX网络编程 卷2》读书笔记(四)    
else if (rw->rw_refcount == -1)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        rw
->rw_refcount = 0;        /* releasing a writer */
《UNIX网络编程 卷2》读书笔记(四)    
else
《UNIX网络编程 卷2》读书笔记(四)        err_dump(
"rw_refcount = %d", rw->rw_refcount);
《UNIX网络编程 卷2》读书笔记(四)
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)        
/* 4give preference to waiting writers over waiting readers */
《UNIX网络编程 卷2》读书笔记(四)        
//写者优先,而只有一个写者
《UNIX网络编程 卷2》读书笔记(四)《UNIX网络编程 卷2》读书笔记(四)
    if (rw->rw_nwaitwriters > 0{
《UNIX网络编程 卷2》读书笔记(四)        
if (rw->rw_refcount == 0)
《UNIX网络编程 卷2》读书笔记(四)            result 
= pthread_cond_signal(&rw->rw_condwriters);//通知等待的那个写者
《UNIX网络编程 卷2》读书笔记(四)
    }
 else if (rw->rw_nwaitreaders > 0)
《UNIX网络编程 卷2》读书笔记(四)        result 
= pthread_cond_broadcast(&rw->rw_condreaders);//通知所有等待的读者
《UNIX网络编程 卷2》读书笔记(四)

《UNIX网络编程 卷2》读书笔记(四)    pthread_mutex_unlock(
&rw->rw_mutex);
《UNIX网络编程 卷2》读书笔记(四)    
return(result);
《UNIX网络编程 卷2》读书笔记(四)}

《UNIX网络编程 卷2》读书笔记(四)

这里的读出锁和写入锁函数都有一个问题,若调用线程阻塞在pthread_cond_wati调用上,并且随后此线程被取消了,则它会在还持有互斥锁的情况下终止,于是rw_nwaitreaders计数器的值会出错