1 producer — n consumers 模型 实现

#include<stdio.h>
#include<string.h>
#include<pthread.h>
#include<stdlib.h>
#include<unistd.h>
#include<queue>
using namespace std;
#define LEN 128
typedef struct task_que
{
queue<char*> string_queue;
int m_flag ; //结束标志
int m_capacity;
pthread_mutex_t m_lock;
pthread_cond_t m_pro , m_con;
}QUE , *pQUE;
void* thd_func(void* arg);
void put(pQUE pq, char* src);
void get(pQUE pq, char* dest);
int main(int argc, char *argv[])
{
QUE aque;
aque.m_flag = ;
int nthds = atoi( argv[] ); //线程的个数
aque.m_capacity = atoi( argv[] );//字符串队列的大小
pthread_mutex_init( &aque.m_lock , NULL ); //锁
pthread_cond_init( &aque.m_pro ,NULL ); //生产者条件变量
pthread_cond_init( &aque.m_con , NULL ); //消费者条件变量
//开辟线程空间
pthread_t *thd_arr = ( pthread_t*)calloc(nthds, sizeof(pthread_t));
int* ntasks = (int*)calloc(nthds, sizeof(int));//用来记录 线程工作了几次
//创建线程
int index;
for(index = ; index < nthds; index ++)
{
pthread_create( thd_arr + index, NULL, thd_func,(void*)&aque );
} //输入字符串到队列中
char buf[LEN] ;
while( memset(buf, , LEN), fgets(buf, LEN, stdin) != NULL)
{
put(&aque, buf);
} //发出结束字符串
strcpy(buf, "over");
put(&aque, buf); for(index = ; index < nthds; index ++)
{
pthread_join(thd_arr[index], (void**)(ntasks + index ));
}
for(index = ; index < nthds; index ++)
{
printf("%d ", ntasks[index]);
}
printf("\n"); pthread_mutex_destroy(&aque.m_lock);
pthread_cond_destroy(&aque.m_pro);
pthread_cond_destroy(&aque.m_con);
return ;
}
void put(pQUE pq, char* src) //把字符串写到队列中
{
pthread_mutex_lock(&pq ->m_lock); //加锁
while(pq ->string_queue.size() == pq ->m_capacity) //队列满则阻塞
{
pthread_cond_wait(&pq -> m_pro, &pq ->m_lock); }
//插入队列
char* tem = ( char*)calloc( LEN , sizeof( char ));
strcpy(tem,src);
pq->string_queue.push(tem);
pthread_mutex_unlock(&pq -> m_lock); //解锁
pthread_cond_broadcast(&pq ->m_con); //唤醒所有消费者线程 } void get(pQUE pq, char* dest)
{
pthread_mutex_lock(&pq ->m_lock); //加锁
while(pq ->m_flag == && pq ->string_queue.empty() ) //队列空 并且未结束 则阻塞
{
pthread_cond_wait(&pq ->m_con, &pq ->m_lock);
}
if(pq ->m_flag == ) //判断结束标志
{
pthread_mutex_unlock(&pq ->m_lock); //解锁
return ;
}
//出队
strcpy(dest, pq ->string_queue.front());
pq->string_queue.pop(); pthread_mutex_unlock(&pq ->m_lock);
pthread_cond_signal(&pq ->m_pro); } void* thd_func(void* arg)
{
pQUE pq = (pQUE)arg ;
char buf[LEN] ;
int ncnt = ;
while()
{
memset(buf, , LEN) ;
get(pq, buf);
if(pq ->m_flag == ) //判断结束标志
{
printf("%u exit!\n", pthread_self());
pthread_exit((void*)ncnt); //退出
}
ncnt ++ ;
printf("%u: %s\n", pthread_self(), buf); //打印字符串
if(strcmp("over", buf) == ) //判断结束字符串
{
pq ->m_flag = ; //把结束符号置为 1
pthread_cond_broadcast(&pq ->m_con); //唤醒所有线程
pthread_exit((void*)ncnt); //退出
}
if(ncnt & == ) sleep(); //简单的负载平衡
}
}
1 producer — n consumers 模型 实现的更多相关文章
- 6张图为你分析Kafka Producer 消息缓存模型
摘要:发送消息的时候, 当Broker挂掉了,消息体还能写入到消息缓存中吗? 本文分享自华为云社区<图解Kafka Producer 消息缓存模型>,作者:石臻臻的杂货铺. 在阅读本文之前 ...
- kafka consumer重复消费问题
在做分布式编译的时候,每一个worker都有一个consumer,适用的kafka+zookeep的配置都是默认的配置,在消息比较少的情况下,每一个consumer都能均匀得到互不相同的消息,但是当消 ...
- python--线程知识详解
Threading用于提供线程相关的操作,线程是应用程序中工作的最小单元. 1.1.threading模块 threading模块建立在_thread模块之上.thread模块以低级=原始的方式来处理 ...
- java 中多线程之间的通讯之等待唤醒机制
wait notify () nitifyAll () 都使用在同步中,因为要对持有监视器(锁)的线程操作 所以要使用在同步中,因为只有同步才具有锁 为什么这些操作线程的方法要定义object类中呢 ...
- 关于LockSupport
concurrent包的基础 Doug Lea 的神作concurrent包是基于AQS (AbstractQueuedSynchronizer)框架,AQS框架借助于两个类:Unsafe(提供CAS ...
- 二十二、Hadoop学记笔记————Kafka 基础实战 :消费者和生产者实例
kafka的客户端也支持其他语言,这里主要介绍python和java的实现,这两门语言比较主流和热门 图中有四个分区,每个图形对应一个consumer,任意一对一即可 获取topic的分区数,每个分区 ...
- IBM developer:Kafka ACLs
Overview In Apache Kafka, the security feature is supported from version 0.9. When Kerberos is enabl ...
- Kafka Frequently Asked Questions
This is intended to be an easy to understand FAQ on the topic of Kafka. One part is for beginners, o ...
- Benchmarking Apache Kafka: 2 Million Writes Per Second (On Three Cheap Machines)
I wrote a blog post about how LinkedIn uses Apache Kafka as a central publish-subscribe log for inte ...
随机推荐
- bzoj1538 [NWERC2017]High Score
网上的题解都很奇怪.. 经过相当长时间的思考,有了一个有效(自认为)的解法 设某一种合法分配方案完成后三个数分别变为a,b,c,其中a>=c,b>=c 此时如果让c减1,让a或b加1(设让 ...
- linux下svn服务器搭建步骤
安装步骤如下: 1.yum install subversion 2.输入rpm -ql subversion查看安装位置,如下图: 我们知道svn在bin目录下生成了几个二进制文件. 输入 sv ...
- c/c++学习系列之取整函数,数据宽度与对齐
浮点数的取整 C/C++取整函数ceil(),floor() double floor(double x); double ceil(double x); 使用floor函数.floor(x)返回的是 ...
- 使用request实现手工输入验证码登录
我们的目标网站是这个http://awehome.com.cn,登录页面是这个http://awehome.com.cn/tenant/login import requests import jso ...
- RTOS之CMSIS-RTOS
CMSIS-RTOS 是实时操作系统的通用 API.它提供了标准化的编程接口,它只是封装了RTX/embos,以后还可能封装freeRTOS,uc/os等等第三方OS,CMSIS RTOS是ARM现在 ...
- SVN中如何去除版本控制器
SVN,大家都熟悉,做项目都知道,不知道你有没有遇到每次提交的代码的时候,都会把bin和obj自动生成的文件夹提交SVN服务器上 其实这里都不需要提交,每次生成都提交,可能还会容易冲突,如何不让bin ...
- ES-什么是elasticsearch
前言 观今宜鉴古,无古不成今.在学习elasticsearch之前,我们要知道,elasticsearch是什么?为什么要学习elasticsearch?以及用它能干什么? 关于elasticsear ...
- VC运行时库(/MD、/MT等)
VC项目属性→配置属性→C/C++→代码生成→运行时库 可以采用的方式有:多线程(/MT).多线程调试(/MTd).多线程DLL(/MD).多线程调试DLL(/MDd).单线程(/ML).单线程调试( ...
- Android:Service通知Activity更新界面
Android有四大组件,其中包括service和activity,那么在使用的过程中,我们最常遇到的问题是他们之间的通信问题. 1.首先Activity调用Service 这个是比较基础的,它有两种 ...
- MediaRecord一些使用记录
今天学习了MediaRecord的使用,第一次使用做个记录. MediaRecord作用是声音录制,使用步骤如下: 1.新建出音频文件代码如下: 先创建出用于存储音频文件 File dir = new ...