#include <pthread.h>
#include <list> using namespace std; template <typename T> class wqueue
{
list<T> m_queue;
pthread_mutex_t m_mutex;
pthread_cond_t m_condv; public:
wqueue() {
pthread_mutex_init(&m_mutex, NULL);
pthread_cond_init(&m_condv, NULL);
}
~wqueue() {
pthread_mutex_destroy(&m_mutex);
pthread_cond_destroy(&m_condv);
}
void add(T item) {
pthread_mutex_lock(&m_mutex);
m_queue.push_back(item);
pthread_cond_signal(&m_condv);
pthread_mutex_unlock(&m_mutex);
}
T remove() {
pthread_mutex_lock(&m_mutex);
while (m_queue.size() == ) {
pthread_cond_wait(&m_condv, &m_mutex);
}
T item = m_queue.front();
m_queue.pop_front();
pthread_mutex_unlock(&m_mutex);
return item;
}
int size() {
pthread_mutex_lock(&m_mutex);
int size = m_queue.size();
pthread_mutex_unlock(&m_mutex);
return size;
}
};
#include <stdio.h>
#include <stdlib.h>
#include <string>
#include "thread.h"
#include "wqueue.h" class WorkItem
{
string m_message;
int m_number; public:
WorkItem(const char* message, int number)
: m_message(message), m_number(number) {}
~WorkItem() {} const char* getMessage() { return m_message.c_str(); }
int getNumber() { return m_number; }
}; class ConsumerThread : public Thread
{
wqueue<WorkItem*>& m_queue; public:
ConsumerThread(wqueue<WorkItem*>& queue) : m_queue(queue) {} void* run() {
// Remove 1 item at a time and process it. Blocks if no items are
// available to process.
for (int i = ;; i++) {
printf("thread %lu, loop %d - waiting for item...\n",
(long unsigned int)self(), i);
WorkItem* item = m_queue.remove();
printf("thread %lu, loop %d - got one item\n",
(long unsigned int)self(), i);
printf("thread %lu, loop %d - item: message - %s, number - %d\n",
(long unsigned int)self(), i, item->getMessage(),
item->getNumber());
delete item;
}
return NULL;
}
}; int main(int argc, char** argv)
{
// Process command line arguments
if ( argc != ) {
printf("usage: %s <iterations>\n", argv[]);
exit(-);
}
int iterations = atoi(argv[]); // Create the queue and consumer (worker) threads
wqueue<WorkItem*> queue;
ConsumerThread* thread1 = new ConsumerThread(queue);
ConsumerThread* thread2 = new ConsumerThread(queue);
thread1->start();
thread2->start(); // Add items to the queue
WorkItem* item;
for (int i = ; i < iterations; i++) {
item = new WorkItem("abc", );
queue.add(item);
item = new WorkItem("def", );
queue.add(item);
item = new WorkItem("ghi", );
queue.add(item);
sleep();
} // Wait for the queue to be empty
while (queue.size() < );
printf("done\n");
exit();
}

producter-consumer 他山之石的更多相关文章

  1. Producter and Consumer

    package pinx.thread; import java.util.LinkedList; import java.util.Queue; public class ProducerConsu ...

  2. python系列之 - 并发编程(进程池,线程池,协程)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  3. Springboot+ActiveMQ(ActiveMQ消息持久化,保证JMS的可靠性,消费者幂等性)

    ActiveMQ 持久化设置: 在redis中提供了两种持久化机制:RDB和AOF 两种持久化方式,避免redis宕机以后,能数据恢复,所以持久化的功能 对高可用程序来说 很重要. 同样在Active ...

  4. python并发编程之进程池,线程池,协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  5. concurrent.futures模块(进程池/线程池)

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  6. Linux互斥锁、条件变量和信号量

    Linux互斥锁.条件变量和信号量  来自http://kongweile.iteye.com/blog/1155490 http://www.cnblogs.com/qingxia/archive/ ...

  7. python课堂整理20----生产者消费者模型

    一.实现功能:店铺生产包子,消费者来吃 import time def producter(): ret = [] for i in range(10): time.sleep(0.1) ret.ap ...

  8. Python之网络编程之concurrent.futures模块

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  9. python并发编程之进程池、线程池、协程

    需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...

  10. Java基础——消息队列

    1.消息队列的适用场景:商品秒杀.系统解耦.日志记录等 2.使用Queue实现消息对列 双端队列(Deque)是 Queue 的子类也是 Queue 的补充类,头部和尾部都支持元素插入和获取阻塞队列指 ...

随机推荐

  1. 【C++】类前置声明范例

    • 在编写C++程序的时候,偶尔需要用到前置声明(Forward declaration).下面的程序中,带注释的那行就是类B的前置说明.这是必须的,因为类A中用到了类B,而类B的声明出现在类A的后面 ...

  2. kettle的下载、安装和初步使用(windows平台下)(图文详解)

    kettle的下载 žKettle可以在http://kettle.pentaho.org/网站下载                   http://sourceforge.net/projects ...

  3. ***PHP基于H5的微信支付开发详解(CI框架)

    这次总结一下用户在微信内打开网页时,可以调用微信支付完成下单功能的模块开发,也就是在微信内的H5页面通过jsApi接口实现支付功能.当然了,微信官网上的微信支付开发文档也讲解的很详细,并且有实现代码可 ...

  4. hdu 3405 删掉某点后 求最小生成树

    给出N个点的坐标 边的权值为两点间的距离 删掉其中某点 求最小生成树的权值和 要求这权值最小 因为最多50个点 所以具体是删哪个点 用枚举假如有4个点 就要求4次最小生成树 分别是2 3 4 | 1 ...

  5. Mysql 模糊匹配(字符串str中是否包含子字符串substr)

    1.LIKE 通常与 % 一同使用,类似于一个元字符的搜索.若substr不在str中,则返回0. 2.INSTR(str,substr) 返回字符串 str 中子字符串的第一次出现位置.若subst ...

  6. 【noip模拟赛10】奇怪的贸易 高精度

    描述 刚结束了CS战斗的小D又进入了EVE的游戏世界,在游戏中小D是一名商人,每天要做的事情就是在这里买东西,再运到那里去卖.这次小D来到了陌生的X星,X星上有n种货物,小D决定每种都买走一些,他用a ...

  7. Spring bean加载多个配置文件

    除了写很简单的加载一个xml,加载多个的情况一直没用到,在公司里也不会由自己处理这个问题,现在需要用到了,就研究验证一下. 使用的案例还是上面的例子. 只有,将原来的beans.xml分成两个部分. ...

  8. for循环改为多线程方式进行执行

    import java.util.concurrent.Executor; import java.util.concurrent.Executors; public class MySearchTe ...

  9. NIO 中的读和写

    概述 读和写是I/O的基本过程.从一个通道中读取很简单:只需创建一个缓冲区,然后让通道将数据读到这个缓冲区中.写入也相当简单:创建一个缓冲区,用数据填充它,然后让通道用这些数据来执行写入操作. 从文件 ...

  10. jQuery Ajax -附示例

    jQuery其实就是一个JavaScript的类库,其将复杂的功能做了上层封装,使得开发者可以在其基础上写更少的代码实现更多的功能. jQuery 不是生产者,而是大自然搬运工. jQuery Aja ...