生产者消费者模型已经很古老了吧,最近写了个OpenMP版的此模型之实现,来分享下。

先说一下模型的大致做法是:

1、生产者需要取任务,生产产品。

2、消费者需要取产品,消费产品。

生产者在生产某个产品之后,要告知消费者此产品已经可以使用了。消费者通过获得可以使用这个信号来取得产品,进一步消费产品。

比如,我们有N个图像需要对每一个图像作滤波或者变换等处理,并且把处理后的结果存到硬盘上。

那么生产者可以将N个图像看成N个任务,每个任务都是独立的,每个任务的计算结果可以看成是产品,消费者就是取这个产品来写入硬盘。

先贴出一个实例代码再作解释。

#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <time.h>

#define jobs 1000
#define sz 102000

#if defined(_WIN32) && defined(_MSC_VER)
#include <windows.h>
double abtic() {
	__int64 freq;
	__int64 clock;
	QueryPerformanceFrequency( (LARGE_INTEGER *)&freq );
	QueryPerformanceCounter( (LARGE_INTEGER *)&clock );
	return (double)clock/freq*1000*1000;
}
#else
#include <time.h>
#include <sys/time.h>
double abtic() {
	double result = 0.0;
	struct timeval tv;
	gettimeofday( &tv, NULL );
	result = tv.tv_sec*1000*1000 + tv.tv_usec;
	return result;
}
#endif /* _WIN32 */

#if 1
double timer;
#define ABTMS timer=abtic();fprintf(stdout,"%4d  ",__LINE__)
#define ABTME fprintf(stdout,"%4d  %8.8fms\n",__LINE__,(abtic()-timer)/1000.0f)
#else
#define ABTMS
#define ABTME
#endif

int main()
{
  char *jbNotReady;
  double *a;
  double *as;
  double *pa;
  int j, k;
	char jbnr;

  a = (double*)malloc(sz*jobs*sizeof(double));
  as = (double*)malloc(jobs*sizeof(double));
  jbNotReady = (char*)malloc(jobs*sizeof(char));

  for (j = 0; j < jobs; j++)
  {
    jbNotReady[j] = 1;

  }
  memset(a, 0, sz*jobs*sizeof(double));
  memset(as, 0, jobs*sizeof(double));
  ABTMS;
#pragma omp parallel sections private(j,k,pa) shared(jbNotReady,as,a)
  {
    // producer
#pragma omp section
    {
      for (j = 0; j < jobs; j++)
      {
        pa = a+j*sz;
        for (k = 0; k < sz; k++)
        {
          pa[k] = 1.0;
        }
        jbNotReady[j] = 0;
#pragma omp flush
      }
    }
    // consumer
#pragma omp section
    {
      for (j = 0; j < jobs; j++)
      {
#pragma omp flush
        while (jbNotReady[j]){
#pragma omp flush
				}
        as[j] = 0.0;
        pa = a+j*sz;
        for (k = 0; k < sz; k++)
        {
          as[j] += pa[k];
        }
        if ((int)(as[j])!=sz)fprintf(stdout, "job id %3d :%f\n", j, as[j]);
      }
    }
  }
  ABTME;
  free(a);
  free(as);
  free(jbNotReady);
  return 0;
}

源代码中,第一个section创建的线程扮演的就是生产者的角色,第二个section扮演消费者角色。j这个变量模拟的是任务编号,第一个section中的循环模拟产生产品。第二个section每次取一个任务,而且是顺序取,通过验证任务是否已经准备好来获得正确的产品。

使用flush制导语句是为了将每个线程的缓存和内存强制保持一致,注意生产者向jbNotReady里写,而消费者只是读数据,不会出现内存中的数据写后读,读后写的问题,每个线程获得的数据都是安全的。

以上代码支持Windows和Linux,GCC4.4以后的版本都可以执行,Windows下只要支持OpenMP的编译器,都可行。

OpenMP实现生产者消费者模型的更多相关文章

  1. 【Windows】用信号量实现生产者-消费者模型

    线程并发的生产者-消费者模型: 1.两个进程对同一个内存资源进行操作,一个是生产者,一个是消费者. 2.生产者往共享内存资源填充数据,如果区域满,则等待消费者消费数据. 3.消费者从共享内存资源取数据 ...

  2. 第23章 java线程通信——生产者/消费者模型案例

    第23章 java线程通信--生产者/消费者模型案例 1.案例: package com.rocco; /** * 生产者消费者问题,涉及到几个类 * 第一,这个问题本身就是一个类,即主类 * 第二, ...

  3. Java里的生产者-消费者模型(Producer and Consumer Pattern in Java)

    生产者-消费者模型是多线程问题里面的经典问题,也是面试的常见问题.有如下几个常见的实现方法: 1. wait()/notify() 2. lock & condition 3. Blockin ...

  4. Java多线程15:Queue、BlockingQueue以及利用BlockingQueue实现生产者/消费者模型

    Queue是什么 队列,是一种数据结构.除了优先级队列和LIFO队列外,队列都是以FIFO(先进先出)的方式对各个元素进行排序的.无论使用哪种排序方式,队列的头都是调用remove()或poll()移 ...

  5. Java多线程14:生产者/消费者模型

    什么是生产者/消费者模型 一种重要的模型,基于等待/通知机制.生产者/消费者模型描述的是有一块缓冲区作为仓库,生产者可将产品放入仓库,消费者可以从仓库中取出产品,生产者/消费者模型关注的是以下几个点: ...

  6. Java生产者消费者模型

    在Java中线程同步的经典案例,不同线程对同一个对象同时进行多线程操作,为了保持线程安全,数据结果要是我们期望的结果. 生产者-消费者模型可以很好的解释这个现象:对于公共数据data,初始值为0,多个 ...

  7. python_way ,day11 线程,怎么写一个多线程?,队列,生产者消费者模型,线程锁,缓存(memcache,redis)

    python11 1.多线程原理 2.怎么写一个多线程? 3.队列 4.生产者消费者模型 5.线程锁 6.缓存 memcache redis 多线程原理 def f1(arg) print(arg) ...

  8. 如何在 Java 中正确使用 wait, notify 和 notifyAll – 以生产者消费者模型为例

    wait, notify 和 notifyAll,这些在多线程中被经常用到的保留关键字,在实际开发的时候很多时候却并没有被大家重视.本文对这些关键字的使用进行了描述. 在 Java 中可以用 wait ...

  9. Python学习笔记——进阶篇【第九周】———线程、进程、协程篇(队列Queue和生产者消费者模型)

    Python之路,进程.线程.协程篇 本节内容 进程.与线程区别 cpu运行原理 python GIL全局解释器锁 线程 语法 join 线程锁之Lock\Rlock\信号量 将线程变为守护进程 Ev ...

随机推荐

  1. Angular1.x使用小结

    之前工作以Angular1.x为主,主要做业务系统,以后工作中技术栈可能以vue为主,在此对Angular1.x的使用做一个简单总结,这里使用1.5+版本. 基本概念 1.依赖注入 依赖注入,在ang ...

  2. Spring Boot 之Hello Word

    Spring Boot官网:http://projects.spring.io/spring-boot/ 环境准备:maven 3.3.5.jdk8.Idea 1.创建maven项目工程 2.引入st ...

  3. 实验吧_貌似有点难(php代码审计)&头有点大

    二话不说先贴代码 <?php function GetIP(){ if(!empty($_SERVER["HTTP_CLIENT_IP"])) $cip = $_SERVER ...

  4. codevs 3061 质子撞击炮②

    提交地址:http://codevs.cn/problem/3016/ 3016 质子撞击炮 II  时间限制: 1 s  空间限制: 32000 KB  题目等级 : 黄金 Gold     题目描 ...

  5. [HNOI 2001]矩阵乘积

    Description Input Output Sample Input 1 2 3 4 2 3 1 1 3 1 4 5 2 2 1 3 1 2 1 2 2 2 1 1 3 1 2 3 2 4 1 ...

  6. [HNOI 2005]狡猾的商人

    Description 刁姹接到一个任务,为税务部门调查一位商人的账本,看看账本是不是伪造的.账本上记录了n个月以来的收入情况,其中第i 个月的收入额为Ai(i=1,2,3...n-1,n), .当 ...

  7. 数轴line

    aaarticlea/png;base64,iVBORw0KGgoAAAANSUhEUgAAAq8AAAGaCAYAAAAhPqoeAAAgAElEQVR4nOzdCbh2U/k/8C0NpkgRzZ

  8. ●POJ 1509 Glass Beads

    题链: http://poj.org/problem?id=1509 题解: 给出一个字符串,有一个操作:把首字符放到末尾,形成新的串.求任意次操作后,字典序最小的串的首字母在原串中的位置.(这就是最 ...

  9. HDU2425:Hiking Trip(BFS+优先队列)

    给出一个地图,地图有四种路面,经过每种路面花费的时间不同,问从起点到终点所花费的最少时间是多少 把到各个点的花费存入队列中,然后弹出,即可得到最小 Sample Input 4 6 1 2 10 T. ...

  10. 关于快速沃尔什变换(FWT)的一点学习和思考

    最近在学FWT,抽点时间出来把这个算法总结一下. 快速沃尔什变换(Fast Walsh-Hadamard Transform),简称FWT.是快速完成集合卷积运算的一种算法. 主要功能是求:,其中为集 ...