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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值