读-写锁

如果线程只是读取共享存储器,那么允许多个线程进入临界区。任意数量的线程可以拥有一个读-写锁来进行读操作,但是如果要写存储器,就只允许一个线程进行访问。读写锁常用于读数据比写数据多的应用中。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

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

  1. 并行与分布式、集群、网格计算、云计算的概念

    转自:http://blog.163.com/litianyichuanqi@126/blog/static/1159794412012387453794/ 一.并行计算与分布式计算 并行计算:并行计 ...

  2. python网络编程基础(线程与进程、并行与并发、同步与异步、阻塞与非阻塞、CPU密集型与IO密集型)...

    python网络编程基础(线程与进程.并行与并发.同步与异步.阻塞与非阻塞.CPU密集型与IO密集型) 目录 线程与进程并行与并发同步与异步阻塞与非阻塞CPU密集型与IO密集型 线程与进程 进程 前言 ...

  3. Actor模型(分布式编程)

    Actor的目的是为了解决分布式编程中的一系列问题.所有消息都是异步交付的,因此将消息发送方与接收方分开,正是由于这种分离,导致actor系统具有内在的并发性:可以不受限制地并行执行任何拥有输入消息的 ...

  4. MapReduce分布式编程模型

    文章目录 MapReduce分布式编程模型 1.定义 2.优缺点 3.MapReduce核心思想 4.MapReduce进程 5.MapReduce编程规范 Hadoop序列化 1.什么是序列化 2. ...

  5. Python多进程编程及多进程间的通信,数据传输

    多进程编程及进程间的通信多进程的优缺点进程(process)三态五态(三态的基础上增加了新建态和终止态)进程优先级进程特征孤儿进程僵尸进程要求理解多进程编程进程相关的函数多进程模块Process()创 ...

  6. 并行与分布式复习笔记

    mulu 链表操作与分析 MPI常用的API与应用 Pthreads常用的API及其应用.互斥锁.忙等待(自旋锁)的实现与应用 OpenMP常用的编译指令及其子句应用 课本典型案例:矩阵向量乘.曲边梯 ...

  7. erlang分布式编程模型

    erlang分布式编程有两种模型 一.分布式erlang 运行在可信的网络环境中 1.rpc提供的远程过程调用 rpc:call(Node,Mode,Fun,Args) ->Result|{ba ...

  8. 19、Java并发编程:线程间协作的两种方式:wait、notify、notifyAll和Condition

    Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition 在前面我们将了很多关于同步的问题,然而在现实中,需要线程之间的协作.比如说最经典的生产者-消费者 ...

  9. python多进程间通信_Python 多进程编程之 进程间的通信(Queue)

    Python 多进程编程之 进程间的通信(Queue) 1,进程间通信 Process有时是需要通信的,操作系统提供了很多机制来实现进程之间的通信,而Queue就是其中的一个方法 ----这是操作系统 ...

最新文章

  1. gcc 编译 java,编译lineage,gcc的版本问题
  2. 【转】jQuery最佳实践
  3. springmvc的原理架构,Struts2运行原理,springmvc和Struts2的区别
  4. (诊断)处理错误fatal error: Python.h: No such file or directory
  5. 多快好省的预训练模型:你丢我也丢
  6. python flask框架教程_Flask框架从入门到实战
  7. 延迟加载是一种代码气味
  8. Java 集合系列目录(Category)
  9. 文件I/O实践(3) --文件共享与fcntl
  10. Python matplotlib画图出现No handles with labels found to put in legend
  11. 【RBM】代码学习--DeepLearningToolBox
  12. 用VB 代码读取 Excel 内容
  13. 对视频图像进行OSD叠加
  14. Android耗电统计算法
  15. 成功解决 KeyError: Unable to open object (object x doesnt exist)和no file found ./SGN/asd.phl
  16. composer install 中出现用户名密码错误问题的解决方法
  17. 纯前端语言编写音乐播放器
  18. DeepLabV3论文解读(空洞卷积/膨胀卷积 理解)
  19. 极客爱情 2.0.1| 从你的编程世界路过
  20. 各种系统架构图及其简介

热门文章

  1. java笔记--关于线程同步(7种同步方式)
  2. 微信小游戏视频激励广告onClose接口叠加回调的问题解决方法
  3. 洛谷P1280 caioj 1085 动态规划入门(非常规DP9:尼克的任务)
  4. myeclipse在weblogic中的开发
  5. iOS Ruby出现问题,导致无法安装Pod
  6. 通过组策略实现IE自动以当前域账号登录某站点
  7. 2014年中回首与展望
  8. Framework7:不会Objective-C,也能开发iOS7应用
  9. 查看Linux硬件信息命令的使用
  10. windows下增加python的库搜索路径