C++ 并行与分布式编程 chapter5 任务间并发的同步(2)

读-写锁

如果线程只是读取共享存储器,那么允许多个线程进入临界区。任意数量的线程可以拥有一个读-写锁来进行读操作,但是如果要写存储器,就只允许一个线程进行访问。读写锁常用于读数据比写数据多的应用中。POSIX定义pthread_rwlock_t为读写锁。它与互斥锁有相同的操作,只是有一个pthread_rwlock_rdlock读封锁操作()和pthread_rwlock_wrlock()写封锁操作。如果一个线程请求读封锁,只要没有任何线程拥有写封锁,就可以授权。如果线程请求写封锁,那么只要没有任何线程拥有读封锁或写封锁,就可以授权。读写锁可以实现CREW并发读互斥写

pthread_t ThreadA,ThreadB,ThreadC,ThreadD;

pthread_rwlock_t RWLock;

void *producer1(void *X)

{

   pthread_rwlock_wrlock(&RWLock);

   //critical section

   pthread_rwlock_unlock(&RWLock);

   return(0);

}

void *producer2(void *X)

{

   pthread_rwlock_wrlock(&RWLock);

   //critical section

   pthread_rwlock_unlock(&RWLock);

}

 void *consumer1(void *X)

{

   pthread_rwlock_rdlock(&RWLock);

   //critical section

   pthread_rwlock_unlock(&RWLock);

   return(0);

}

 

void *consumer2(void *X)

{

   pthread_rwlock_rdlock(&RWLock);

   //critical section

   pthread_rwlock_unlock(&RWLock);

   return(0);

}

 

int main(void)

{

   pthread_rwlock_init(&RWLock,NULL);

   //set mutex attributes

   pthread_create(&ThreadA,NULL,producer1,NULL);

   pthread_create(&ThreadB,NULL,consumer1,NULL);

   pthread_create(&ThreadC,NULL,producer2,NULL);

   pthread_create(&ThreadD,NULL,consumer2,NULL);

   //...

   return(0);

}

ThreadB and ThreadD can enter their critical sections concurrently or serially but neither thread can enter their critical sections if either ThreadA or ThreadC is in theirs. ThreadA and ThreadC cannot enter their critical sections concurrently
条件变量Condition Variable用来发送事件发生信号的信号量。一旦事件发生,或多个进程或者线程就等待其他进程或线程发送信号。生产者线程发送信号通知消费者线程对象已经加入到队列中。消费者线程在接收到信号之前处于等待状态,接收到信号后就继续处理队列。

条件变量可以和互斥锁一起使用:当一个任务试图加锁,如果互斥锁已经加锁了,这个任务就会被阻塞。如果使用一个条件变量,该条件变量必须与一个互斥锁相关联。一旦不被阻塞,任务就会释放互斥锁Mutex,同时等待条件变量EventMutex。发送信号操作在时间按发生时是任务向另一个线程或进程发送信号,如果一个任务在等待那个条件变量,那么该任务就不再被阻塞,并获得互斥锁。条件变量可以实现4种基本同步关系FF、FS、SS、SF

#pragma comment(lib, "pthreadVC2.lib")

#include <pthread.h>

#include <iostream>

using namespace std;

float Number;

pthread_t ThreadA,ThreadB;

pthread_mutex_t Mutex,EventMutex;

pthread_cond_t Event;

void *worker1(void *X)

{

         for(int Count = 1;Count < 100;Count++){

                   pthread_mutex_lock(&Mutex);

                   Number++;

                   pthread_mutex_unlock(&Mutex);

                   cout << "worker1: number is " << Number << endl;

                   if(Number == 50){

                            pthread_cond_signal(&Event);

                   }

         }

         cout << "worker 1 done" << endl;

         return(0);

}

 void *worker2(void *X)

{

         pthread_mutex_lock(&EventMutex);

         pthread_cond_wait(&Event,&EventMutex);

         pthread_mutex_unlock(&EventMutex);

         cout<<"work2 is started! Now, Number is:"<<Number<<endl;

         for(int Count = 1;Count < 50;Count++){

                   pthread_mutex_lock(&Mutex);

                   Number = Number + 20;

                   pthread_mutex_unlock(&Mutex);

                   cout << "worker2: number is " << Number << endl;

         }

         cout << "worker 2 done" << endl;

         return(0);

}

int main(int argc, char *argv[])

{

         pthread_mutex_init(&Mutex,NULL);

         pthread_mutex_init(&EventMutex,NULL);

         pthread_cond_init(&Event,NULL);

         cout<<"start thread A & B"<<endl;

         pthread_create(&ThreadA,NULL,worker1,NULL);

         pthread_create(&ThreadB,NULL,worker2,NULL);

         //...

         pthread_join(ThreadA,NULL);//wait for threads

         pthread_join(ThreadB,NULL);

         return(0);

}

实现了FS同步关系。在线程B开始之前线程A不能结束。一旦Number==50,ThreadA就发送信号给ThreadB,接着线程A继续执行直到结束。在接收到A的信号后,B才开始计算。线程B使用EventMutex与条件变量Event.Mutex来同步共享数据Number的写访问。一个任务可以使用几个互斥锁来同步不同的临界区以及不同的事件。

本文使用Blog_Backup未注册版本导出,请到soft.pt42.com注册。

原文链接: https://www.cnblogs.com/aquar/archive/2010/11/19/3451395.html

欢迎关注

微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍

    C++ 并行与分布式编程 chapter5 任务间并发的同步(2)

原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/17597

非原创文章文中已经注明原地址,如有侵权,联系删除

关注公众号【高性能架构探索】,第一时间获取最新文章

转载文章受原作者版权保护。转载请注明原作者出处!

(0)
上一篇 2023年2月7日 下午6:12
下一篇 2023年2月7日 下午6:12

相关推荐