编译环境:Ubuntu16.04 64位
交叉编译工具:arm-hisiv500-linux-gcc
文章目录
- 1. 背景
- 2. 涉及的函数
- 3. 头文件JList.h
- 4. 类的实现
1. 背景
最近项目中需要用到多线程通信,自己造个轮子吧,对照上一篇linux c共享内存和信号量。
2. 涉及的函数
详细描述可以百度或ubuntu下查询man手册。
互斥锁相关:
int pthread_mutex_init(pthread_mutex_t * mutex, const pthread_mutexattr_t * attr);
int pthread_mutex_destroy(pthread_mutex_t *mutex);
int pthread_mutex_lock(pthread_mutex_t *mutex);
int pthread_mutex_unlock(pthread_mutex_t *mutex);
3. 头文件JList.h
#ifndef __J_LIST__
#define __J_LIST__#ifdef __cplusplus
extern "C" {
#endiftypedef enum _JLIST_ERR{JLIST_NO_DATA = -4, // 无数据供读取JLIST_READ_LENGTH_ERR = -3, // 读取缓冲区长度不够JLIST_WRITE_LENGTH_ERR = -2, // 写入长度超出JLIST_INIT_FAIL = -1, // 初始化异常JLIST_OK = 0,JLIST_WRITE_OVERWRITE = 1, // 写成功,但是覆盖
}JLIST_ERR;class JList {
public:JList(unsigned int size, unsigned int blockNum = 0);~JList();int Write(unsigned char *buf, unsigned int len);int Read(unsigned char *buf, unsigned int len);private:static unsigned int IsPower2(unsigned int size); static unsigned int To2N(unsigned int size);
private:unsigned int m_size; // 内存总大小unsigned int m_blockSize; // 块大小unsigned int m_blockNum; // 块数量unsigned char *m_buffer; // 内存地址unsigned int m_offset; // 数据偏移量pthread_mutex_t m_mutex;};#ifdef __cplusplus
}
#endif
#endif // __J_LIST__
4. 类的实现
#include <string.h>
#include <stdlib.h>#include "JList.h"struct ListHead {unsigned int readPos; // 读取位置,从0开始,blockNum不为0时有效unsigned int dataNum; // 数据数量unsigned int len[0]; // 数据长度,根据blockNum分配
};unsigned int JLIST::IsPower2(unsigned int size)
{if (size == 0)return 0;return ((size & (size - 1)) == 0);
}unsigned int JLIST::To2N(unsigned int size)
{unsigned int i = 1;unsigned int tmp = size;while (size >>= 1){i <<= 1;}return (i < tmp) ? i << 1 : i;
}JList::JList(unsigned int blockSize, unsigned int blockNum)
{unsigned int nSize = IsPower2(blockSize) ? blockSize : To2N(blockSize);m_blockSize = nSize;m_blockNum = (blockNum == 0) ? 1 : blockNum;m_offset = sizeof(ListHead) + sizeof(unsigned int) * m_blockNum;m_size = m_blockSize * m_blockNum + m_offset;m_buffer = (unsigned char *)malloc(m_size);memset(m_buffer, 0, m_size);pthread_mutex_init(&m_mutex, NULL);
}JList::~JList()
{free(m_buffer);m_buffer = NULL;pthread_mutex_destroy(&m_mutex);
}// !!!note:写入内存,写入长度需要小于等于块长度
// buf:要写入的数据
// len:要写入的数据的长度
// 返回值:>=0表示成功,0成功,1覆盖旧数据,-1表示失败
int JList::Write(unsigned char *buf, unsigned int len)
{if (m_buffer == NULL)return JLIST_INIT_FAIL;if (len > m_blockSize)return JLIST_WRITE_LENGTH_ERR; int ret = JLIST_OK;pthread_mutex_lock(&m_mutex);ListHead *head = (ListHead *)m_buffer; unsigned int writePos = head->readPos + head->dataNum;if (writePos >= m_blockNum)writePos = writePos - m_blockNum;memcpy(m_buffer + m_offset + m_blockSize * writePos, buf, len);head->len[writePos] = len;if (head->dataNum == m_blockNum) // 满的{head->readPos = (writePos + 1 >= m_blockNum) ? 0 : writePos + 1;ret = JLIST_WRITE_OVERWRITE;}else{head->dataNum = head->dataNum + 1;}pthread_mutex_unlock(&m_mutex);return ret;
}// !!!note:读取内存,读取长度需要大于等于数据长度
// buf:读数据的缓冲区
// len:缓冲区的长度
// 返回值:实际读取到的长度,<=0表示失败
int JList::Read(unsigned char *buf, unsigned int len)
{if (m_buffer == NULL)return JLIST_INIT_FAIL;int ret = JLIST_OK;pthread_mutex_lock(&m_mutex);ListHead *head = (ListHead *)m_buffer;if (head->dataNum == 0){pthread_mutex_unlock(&m_mutex);return JLIST_NO_DATA;}unsigned int readPos = head->readPos;if (len < head->len[readPos]){pthread_mutex_unlock(&m_mutex);return JLIST_READ_LENGTH_ERR;}memcpy(buf, m_buffer + m_offset + m_blockSize * readPos, head->len[readPos]);ret = head->len[readPos];head->readPos = (readPos + 1 >= m_blockNum) ? 0 : readPos + 1;head->dataNum = head->dataNum - 1;pthread_mutex_unlock(&m_mutex);return ret;
}
以上。
转载请注明出处,如有错漏之处,敬请指正。