C++ 并行与分布式编程 chapter5 任务间并发的同步(2)
2010-11-19 19:43
405 查看
读-写锁如果线程只是读取共享存储器,那么允许多个线程进入临界区。任意数量的线程可以拥有一个读-写锁来进行读操作,但是如果要写存储器,就只允许一个线程进行访问。读写锁常用于读数据比写数据多的应用中。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注册。
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注册。
相关文章推荐
- C++ 并行与分布式编程 chapter5 任务间并发的同步(1)
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C++并行与分布式编程chater3 将C++程序分成多个任务
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C# 并行编程 之 Barrier的使用 - 通过屏障同步并发任务
- C++并发编程实战chapter1你好,C++的并发世界--笔记1--任务并行和数据并行
- C++11 并发编程基础(一):并发、并行与C++多线程
- C++11 并发编程基础(一):并发、并行与C++多线程
- Hadoop并行计算原理与分布式并发编程
- GCD编程dispatch_sync(同步)和dispatch_async(异步)方式执行并发队列任务区别
- Hadoop并行计算原理与分布式并发编程
- Java 并发编程实战学习笔记——串行任务转并行任务
- Atitit 三种并发编程模型 艾龙 attilax总结 1. 并发系统可以使用不同的并发模型去实现。 1 2. 并行工作者 并行工作者模型。进来的任务分配给不同的工作者 银行模式 2 2.1.
- Java 并发编程实战学习笔记——路径查找类型并行任务的终止
- Java 并发编程之任务取消(五)
- 同步异步,并发并行、多线程 比较
- Java高并发编程——为IO密集型应用设计线程数与划分任务
- 并发,并行,同步,异步,多线程的区别
- 用 Hadoop 进行分布式并行编程, 第 1 部分
- 并发编程实战学习笔记(十)-构建自定义的同步工具