线程消息队列c语言,基于C语言的线程通信消息队列实现

#include #include "msg_process.h"

#define LOG_ERR(fmt, ...) do{\

printf("[ERROR] "fmt" [line:%d] [%s]\n", ##__VA_ARGS__, __LINE__, __FUNCTION__);\

}while(0);

static unsigned long timeout_ns = 0;

/**

* 消息处理模块内部接口

*/

static void put_msg_to_buffer(tmsg_buffer* buf, tmsg_element* elm){

if (NULL == buf || NULL == elm) {

return;

}

if (NULL != elm->next) {

elm->next = NULL;

}

pthread_mutex_lock(&buf->mutex);

//缓冲区中无消息节点

if (0 == buf->num) {

gettimeofday(&timenow,NULL);

timeout.tv_sec = timenow.tv_sec + block/1000; //加上秒数

block %= 1000;//得到毫秒数

timeout_ns = timenow.tv_usec*1000 + block*1000*1000;

if( timeout_ns >= 1000*1000*1000 ) //若超过1s

{

timeout.tv_sec ++;

timeout.tv_nsec = timeout_ns - 1000*1000*1000;

}

else

timeout.tv_nsec = timeout_ns;

//带超时时间阻塞线程等待消息节点

pthread_cond_timedwait(&buf->not_empty, &buf->mutex, &timeout);

}

pthread_mutex_unlock(&buf->mutex);

}

static tmsg_element* get_msg_from_buffer(tmsg_buffer* buf, int block){

tmsg_element *elm = NULL;

if (NULL == buf) {

return NULL;

}

pthread_mutex_lock(&buf->mutex);

//缓冲区中无消息节点

while (0 == buf->num) {

//阻塞线程等待消息节点

pthread_cond_wait(&buf->not_empty, &buf->mutex);

}

//从缓冲区首部取出消息节点

elm = buf->first;

if (1 == buf->num) {

buf->first = buf->last = NULL;

buf->num = 0;

} else {

buf->first = buf->first->next;

buf->num --;

}

pthread_mutex_unlock(&buf->mutex);

return elm;

}

static tmsg_element* get_msg_from_buffer_timeout(tmsg_buffer* buf, int block/*ms*/){

tmsg_element *elm = NULL;

struct timeval timenow;

struct timespec timeout;

if (NULL == buf) {

return NULL;

}

pthread_mutex_lock(&buf->mutex);

//缓冲区中无消息节点

if (0 == buf->num) {

gettimeofday(&timenow);

timeout.tv_sec = timenow.tv_sec;

timeout.tv_nsec = (timenow.tv_usec + block * 1000) * 1000;

//带超时时间阻塞线程等待消息节点

pthread_cond_timedwait(&buf->not_empty, &buf->mutex, &timeout);

}

if (buf->num > 0) {

//从缓冲区首部取出消息节点

elm = buf->first;

if (1 == buf->num) {

buf->first = buf->last = NULL;

buf->num = 0;

} else {

buf->first = buf->first->next;

buf->num --;

}

}

pthread_mutex_unlock(&buf->mutex);

return elm;

}

static tmsg_element* clear_msg_buffer(tmsg_buffer* buf){

tmsg_element* elm = NULL;

tmsg_element* elm_tmp = NULL;

if (NULL == buf){

return NULL;

}

//清空buffer中当前消息节点之前的所有消息节点

pthread_mutex_lock(&buf->mutex);

if (buf->num > 0) {

elm = buf->first;

while(elm != NULL) {

//首尾指针指向同一消息节点

if (elm == buf->last) {

buf->first = buf->last;

if (buf->num != 1) {

buf->num = 1;

}

break;

}

elm_tmp = elm->next;

free_tmsg_element(elm);

buf->num --;

elm = elm_tmp;

buf->first = elm;

}

}

pthread_mutex_unlock(&buf->mutex);

return elm;

}

static void send_msg_to_buffer(tmsg_buffer* buf, int msg, int ext, char* str, int len)

{

tmsg_element *elm = NULL;

elm = (tmsg_element *)malloc(sizeof(tmsg_element));

if (NULL == elm) {

LOG_ERR("new msg element failed!!");

return;

}

//填充消息节点数据

memset(elm, 0, sizeof(tmsg_element));

elm->msg = msg;

elm->ext = ext;

elm->dt = NULL;

elm->dt_len = len;

if (str)

{

elm->dt = (char *)malloc(len); //根据发送的大小申请内存

memmove(elm->dt, str, len);

}

elm->next = NULL;

//将消息节点添加到缓冲区中

put_msg_to_buffer(buf, elm);

}

static void send_msg_to_buffer_ex(tmsg_buffer* buf, int msg, int ext, int sub0, int sub1, char* str, int len){

tmsg_element *elm = NULL;

elm = (tmsg_element *)malloc(sizeof(tmsg_element));

if (NULL == elm) {

LOG_ERR("new msg element failed!!");

return;

}

//填充消息节点数据

memset(elm, 0, sizeof(tmsg_element));

elm->msg = msg;

elm->ext = ext;

elm->sub0 = sub0;

elm->sub1 = sub1;

elm->dt = NULL;

elm->dt_len = len;

if (str)

{

elm->dt = (char *)malloc(len); //根据发送的大小申请内存

memmove(elm->dt, str, len);

}

elm->next = NULL;

//将消息节点添加到缓冲区中

put_msg_to_buffer(buf, elm);

}

static void dispose_msg_buffer(tmsg_buffer* buf){

tmsg_element* elm = NULL;

if (NULL == buf) {

return;

}

if (buf->first != buf->last

&& buf->num > 0) {

elm = clear_msg_buffer(buf);

} else {

elm = buf->last;

}

if (NULL != elm) {

free_tmsg_element(elm);

buf->first = buf->last = NULL;

buf->num = 0;

}

pthread_mutex_destroy(&buf->mutex);

pthread_cond_destroy(&buf->not_empty);

free(buf);

buf = NULL;

}

static int get_msg_num(tmsg_buffer* buf){

if (NULL == buf) {

return 0;

}

return buf->num;

}

/**

* 以下为消息处理模块对外接口

*/

/*消息缓冲区初始化*/

tmsg_buffer* msg_buffer_init(void){

tmsg_buffer* msg_buffer = NULL;

msg_buffer = (tmsg_buffer *)malloc(sizeof(tmsg_buffer));

if (NULL == msg_buffer){

LOG_ERR("init msg buffer failed!!");

return NULL;

}

//初始化成员变量和函数

memset(msg_buffer, 0, sizeof(tmsg_buffer));

msg_buffer->first = NULL;

msg_buffer->last = NULL;

msg_buffer->num = 0;

pthread_mutex_init(&(msg_buffer->mutex), NULL);

pthread_cond_init(&(msg_buffer->not_empty), NULL);

//继续绑定接口

msg_buffer->put = put_msg_to_buffer;

msg_buffer->get = get_msg_from_buffer;

msg_buffer->get_timeout = get_msg_from_buffer_timeout;

msg_buffer->clear = clear_msg_buffer;

msg_buffer->sendmsg = send_msg_to_buffer;

msg_buffer->sendmsgex = send_msg_to_buffer_ex;

msg_buffer->dispose = dispose_msg_buffer;

msg_buffer->getnum = get_msg_num;

return msg_buffer;

}

/*复制消息节点*/

tmsg_element* dup_msg_element(tmsg_element* elm){

tmsg_element* msg_element = NULL;

if (NULL == elm) {

LOG_ERR("msg element is NULL!!");

return NULL;

}

msg_element = (tmsg_element *)malloc(sizeof(tmsg_element));

if (NULL == msg_element) {

LOG_ERR("create msg element is failed!!");

return NULL;

}

memcpy(msg_element, elm, sizeof(tmsg_element));

return msg_element;

}

void free_tmsg_element(tmsg_element *msg_element)

{

if(msg_element != NULL)

{

if(msg_element->dt != NULL)

{

free(msg_element->dt);

msg_element->dt = NULL;

}

free(msg_element);

msg_element = NULL;

}

}

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值