producter-consumer 他山之石
#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 他山之石的更多相关文章
- Producter and Consumer
package pinx.thread; import java.util.LinkedList; import java.util.Queue; public class ProducerConsu ...
- python系列之 - 并发编程(进程池,线程池,协程)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Springboot+ActiveMQ(ActiveMQ消息持久化,保证JMS的可靠性,消费者幂等性)
ActiveMQ 持久化设置: 在redis中提供了两种持久化机制:RDB和AOF 两种持久化方式,避免redis宕机以后,能数据恢复,所以持久化的功能 对高可用程序来说 很重要. 同样在Active ...
- python并发编程之进程池,线程池,协程
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- concurrent.futures模块(进程池/线程池)
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Linux互斥锁、条件变量和信号量
Linux互斥锁.条件变量和信号量 来自http://kongweile.iteye.com/blog/1155490 http://www.cnblogs.com/qingxia/archive/ ...
- python课堂整理20----生产者消费者模型
一.实现功能:店铺生产包子,消费者来吃 import time def producter(): ret = [] for i in range(10): time.sleep(0.1) ret.ap ...
- Python之网络编程之concurrent.futures模块
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- python并发编程之进程池、线程池、协程
需要注意一下不能无限的开进程,不能无限的开线程最常用的就是开进程池,开线程池.其中回调函数非常重要回调函数其实可以作为一种编程思想,谁好了谁就去掉 只要你用并发,就会有锁的问题,但是你不能一直去自己加 ...
- Java基础——消息队列
1.消息队列的适用场景:商品秒杀.系统解耦.日志记录等 2.使用Queue实现消息对列 双端队列(Deque)是 Queue 的子类也是 Queue 的补充类,头部和尾部都支持元素插入和获取阻塞队列指 ...
随机推荐
- jQuery插件实践之轮播练习(一)
所有文章搬运自我的个人主页:sheilasun.me 因为从来没写过jQuery插件,所以本文要通过一个轮播的例子,练习jQuery插件的写法. 新建插件文件 在讨论细节之前,先新建插件文件(当然也可 ...
- 不同git仓库版本控制
场景: 我们有一个开源项目托管在github上面,现在打算在gitlab上进行私有托管开发,当适合发布一个版本的时候提交到github. Git合并特定commits 到另一个分支 实现如下: 1.获 ...
- jenkins X实践系列(2) —— 基于jx的DevOps实践
jx是云原生CICD,devops的一个最佳实践之一,目前在快速的发展成熟中.最近调研了JX,这里为第2篇,使用已经安装好的jx来实践CICD,旨在让大家了解基于jx的DevOps是如何运转的,感兴趣 ...
- Codeforces 269C Flawed Flow (看题解)
我好菜啊啊啊.. 循环以下操作 1.从队列中取出一个顶点, 把哪些没有用过的边全部用当前方向. 2.看有没有点的入度和 == 出度和, 如果有将当前的点加入队列. 现在有一个问题就是, 有没有可能队列 ...
- char *s 与 char s[ ]的区别
程序的内存分配 一个由C/C++编译的程序占用的内存分为以下几个部分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数的参数值,局部变量的值等.其 操作方式类似于数据结构中的栈. 2.堆区( ...
- 洛谷 p1123 取数游戏【dfs】
题目链接:https://www.luogu.org/problemnew/show/P1123 转载于:>>>>>> 题目描述 一个N×M的由非负整数构成的数字矩 ...
- Docker启动mysql的坑2
正确启动mysql: docker run -p 3306:3306 --name mysql02 -e MYSQL_ROOT_PASSWORD=123456 -d mysql 此时虽然启动成功.但是 ...
- go标准库-log包源码学习
log包是go语言提供的一个简单的日志记录功能,其中定义了一个结构体类型 Logger,是整个包的基础部分,包中的其他方法都是围绕这整个结构体创建的. Logger结构 Logger结构的定义如下: ...
- Android弹出Toast工具类总结
Android弹出Toast工具类总结,包括系统自带的,也包括自定义的. public class ToastUtil { public ToastUtil() { } public static T ...
- 20172302《程序设计与数据结构》实验四Android程序设计实验报告
课程:<程序设计与数据结构> 班级: 1723 姓名: 侯泽洋 学号:20172302 实验教师:王志强老师 实验日期:2018年5月30日 必修/选修: 必修 1.实验内容 (1)And ...