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 ...
随机推荐
- 洛谷 P1031 均分纸牌
P1031 均分纸牌 这道题告诉我们,对于实在想不出算法的题,可以大胆按照直觉用贪心,而且在考试中永远不要试着去证明贪心算法,因为非常难证,会浪费大量时间. (这就是你们都不去证的理由??) 这道题贪 ...
- Windows忘记mysql的密码
1.查看mysql的安装路径 show variables like "%char%"; 路径:C:\Program Files\MySQL\MySQL Server 5.7\ 2 ...
- WPF 控件树
WPF控件树按照基类进行分类,记录下来便于编写自定义控件时查阅 RangeBase范围控件 Thumb拖到控件 TextBoxBase文本控件 ItemControl组控件 ContrentContr ...
- aspx页面调用webapi接口报错:远程服务器返回错误:(500)内部服务器错误
代码在运行到response = (HttpWebResponse)request.GetResponse();就开始报错 原因:可能因为所调用的接口不存在或者接口中存在错误,可用postman测试接 ...
- 用redis实现简单的队列
在工作中,时常会有用到队列的场景,比较常见的用rabbitMQ这些专业的组件,官网地址是:http://www.rabbitmq.com,重要的是官方有.net的客户端,但是如果对rabbitMQ不熟 ...
- 理解C#系列 / 前言
前言 索引 写什么? 为什么写? 怎么写? 写什么? 写和C#编程相关的知识. 写知识的定义,附加对知识的理解. 写知识的作用,使用的场景,使用的条件. 写知识的本质,技术的结构,工作的原理. 写知识 ...
- PLSQL连接Oracle64监听和服务的配置!
前言: 这里不会涉及到太多关于版本问题的解决,只是简单提一下基本的监听和服务配置问题的解决,让你可以快速的用PLSQL连接上你自己创建的Oracle数据库(这里示例数据库名为ORCL); 版本问题: ...
- uvm_reg_defines——寄存器模型(四)
文件: src/marcos/uvm_reg_defines 类: 无 该文件是寄存器模型src/reg/* 文件对于的宏文件,主要定义了寄存器地址位宽,寄存器数据位宽,字节的大小.计算机从最初的8, ...
- run_test() 验证平台的入口
Run,just run! ——阿甘正传 一个简单的例子: module tb_top; dut u_dut (); initial begin run_test(); end config ...
- IDEA 启用/禁用 Run Dashboard
一.启用 方式一: 创建/打开一个SpringBoot项目[或者点击Run --> Edit Configurations 添加 Spring Boot 类型的项目配置:或者如图在红框处添加配置 ...