linux c++ 循环消息队列写法

很多场合,我们需要一个循环消息处理模式,一个线程产生消息,一个线程进行处理。产生消息的线程就不用阻塞了,可以用了干其他的事情了。常见串口或者网络通信,负责解析字节流的线程将消息初步解析然后放置到一个消息队列里面,处理线程负责循环取出消息队列里面的消息进行相应的动作。下面是一在liunx下一个基本实现框架:

typedef struct Message
{
	char * msg;
	char * res;
	Message(void)
	{
		msg = NULL;
		res = NULL;
	}
	void Init(const char *m,const char * r)
	{
		if(m && strlen(m)>0)
		{
			msg = (char *)malloc(strlen(m)+1);
			if(msg)
			{
				memset(msg,0,strlen(m)+1);
				strcpy(msg,m);
			}
		}
		else
		{
			msg = NULL;
		}
		if(r && strlen(r)>0)
		{
			res = (char *)malloc(strlen(r)+1);
			if(res)
			{
				memset(res,0,strlen(r)+1);
				strcpy(res,r);
			}
		}
		else
		{
			res = NULL;
		}
	}
	void Free()
	{
		if(msg)
			free(msg);
		if(res)
			free(res);
	}
}Message;
//消息队列
typedef struct Msg_list
{
	pthread_mutex_t lock;
	pthread_cond_t cond;
	std::list<Message> msg_list;
	Msg_list()
	{
		pthread_mutex_init(&lock,NULL);
		pthread_cond_init(&cond,NULL);
	}
	void push(Message m)
	{
		pthread_mutex_lock(&lock);
		msg_list.push_back(m);
		pthread_mutex_unlock(&lock);
		pthread_cond_signal(&cond);
	}
	Message pop()
	{
		int get =0 ;
		Message message;
		do{
			if(!msg_list.empty())
			{
				message = msg_list.front();
				msg_list.pop_front();
				get = 1;
			}
			else
			{
				pthread_mutex_lock(&lock);
				pthread_cond_wait(&cond,&lock);//进入该函数会释放lock,等待cond收到信号后,会锁定lock
				pthread_mutex_unlock(&lock);
			}
		}while(!get);
		return message;
	}
}Msg_list;

Msg_list g_messages;
//消费者线程
void * msg_handle_thr(void * arg)
{
	Message m;
	while(1)
	{
		m = g_messages.pop();
		if(m.msg && m.res)
		{
			printf("msg:[%s]\n",m.msg);
			#if DEMO_360
			int type = -1;
			json_object *msg_obj = NULL;
			const char *file = NULL;
			const char *url = NULL;
			//这里解析msg消息体,以下解析方式只是我们的demo示例。
			msg_obj = json_tokener_parse(m.msg);
		    if(is_error(msg_obj))
		    {
		    	printf("msg is invalid\n");
				goto con;
		    }
			type = json_helper_get_int(msg_obj, "type",-1);
			if(2 == type)
			{
				file = json_helper_get_str(msg_obj,"video_name");
				if(file)
				{
					//这里就是将res原封不动的返回给SDK
					Qihoo_IOTS_upload_file(file,m.res);
				}
			}
			else if(1 == type)
			{
				url = json_helper_get_str(msg_obj,"url");
				if(url)
				{
					//这里就是将res原封不动的返回给SDK
					if(Qihoo_IOTS_download_file("/tmp/12345.mp4",url,m.res) == 0)
					{
						printf("send response\n");
						//这里就是将res原封不动的返回给SDK
						Qihoo_IOTS_send_response("ok",m.res);
					}
				}
			}
			else
			{
				printf("User message type:%d\n",type);
			}
		con:
			if(msg_obj != NULL && !is_error(msg_obj))
		        json_helper_put_safe(msg_obj);
			#endif
		}
		m.Free();
	}
	
	return NULL;
}
//生产者线程
void recive_msg(const char* msg,const char*res)
{
	/*注意:该接口中只是将消息插入list,并未处理,
	 *因为该接口不能够阻塞,需要立即返回。
	 *msg为实际收到的消息体,
	 *res为一些接口的依赖信息,应用中并不需要解析,只是暂存,然后再塞给相应的接口。
	 *
	 */
	Message message;
	message.Init(msg,res);
	g_messages.push(message);
	return;
}


  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值