这里实现一个消息队列,作用是为了解决多个线程同时操作一个串口的问题
/*
* @Description: 协议管理器
* @Version: 1.0
* @Autor: zys
* @Date: 2020-09-30 13:18:34
* @LastEditors: zhangyasheng
* @LastEditTime: 2020-11-30 14:01:07
*/
#ifndef __INPUT_MANAGER_H_
#define __INPUT_MANAGER_H_
#include "amt_manager.h"
//队列深度
#define BUFFER_LEN 20
//输入管理器
typedef struct InputOpr{
int read;
int write;
DeviceItem devices[BUFFER_LEN];//消息类型
}InputOpr,*PInputOpr;
void InitInputBuffer(PInputOpr opr);
int putInputBuffer(PInputOpr opr,PDeviceItem data);
int getInputBuffer(PInputOpr opr,PDeviceItem data);
extern InputOpr g_InputOpr_485;
extern InputOpr g_InputOpr_232;
#endif // DEBUG
/*
* @Descripttion:
* @version: 1.0.0
* @Author: zhangyasheng
* @Date: 2020-11-10 12:42:34
* @LastEditors: zhangyasheng
* @LastEditTime: 2020-11-30 14:03:46
*/
#include <stdio.h>
#include <unistd.h>
#include <semaphore.h>
#include <string.h>
#include <pthread.h>
#include "input_manager.h"
//每个接口都对应一个输入队列
InputOpr g_InputOpr_485;
InputOpr g_InputOpr_232;
static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
static int isInputBufferFull(PInputOpr opr)
{
return (opr->read == ((opr->write + 1) % BUFFER_LEN));
}
static int isInputBufferEmpty(PInputOpr opr)
{
return (opr->read == opr->write);
}
void InitInputBuffer(PInputOpr opr)
{
opr->read = 0;
opr->write = 0;
}
int putInputBuffer(PInputOpr opr,PDeviceItem data)
{
pthread_mutex_lock(&mutex);
if(!isInputBufferFull(opr))
{
opr->devices[opr->write] = *data;//这里是拷贝消息
opr->write = (opr->write + 1) % BUFFER_LEN;
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_mutex_unlock(&mutex);
return -1;
}
int getInputBuffer(PInputOpr opr,PDeviceItem data)
{
if(!isInputBufferEmpty(opr))
{
*data = opr->devices[opr->read];
opr->read = (opr->read + 1) % BUFFER_LEN;
return 0;
}
return -1;
}
/*
* @Description: gateway
* @Version: 1.0
* @Autor: zys
* @Date: 2020-09-30 09:47:19
* @LastEditors: zhangyasheng
* @LastEditTime: 2020-11-30 14:17:29
*/
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <string.h>
#include "input_manager.h"
#define THREAD_NUM 7
int main(int argc,char* argv[])
{
pthread_t athread[THREAD_NUM];
int ret=0,i;
InitInputBuffer(&g_InputOpr_485);
InitInputBuffer(&g_InputOpr_232);
//查询任务
#if RS485_EN
ret=pthread_create(&athread[1],NULL,(void*)poll_485,NULL);
if(ret){
printf("Create polling_task err!\n");
}
ret=pthread_create(&athread[3],NULL,(void*)driver_485,NULL);
if(ret){
printf("Create polling_task err!\n");
}
#endif
#if RS232_EN
ret=pthread_create(&athread[2],NULL,(void*)poll_232,NULL);
if(ret){
printf("Create polling_task err!\n");
}
ret=pthread_create(&athread[4],NULL,(void*)driver_232,NULL);
if(ret){
printf("Create polling_task err!\n");
}
#endif
ret=pthread_create(&athread[5],NULL,(void*)net_input,NULL);
if(ret){
printf("Create polling_task err!\n");
}
ret=pthread_create(&athread[6],NULL,(void*)update_sql,NULL);
if(ret){
printf("Create polling_task err!\n");
}
for (i = 0; i < THREAD_NUM; i++)
{
pthread_join(athread[i],NULL);
}
printf("Gateway end\n");
return 0;
}
优化
上面的代码虽然解决了多线程操作一个线程的问题,但是串口的处理结果没法通知前面的线程。如何把下图虚线部分的功能实现呢?
如果要实现我的需求,则需要实现指针的传递,队列里面保存的是指针,修改如下
注意:输入消息队列里面的消息一定是个全部变量!
//输入管理器
typedef struct InputOpr{
int read;
int write;
//DeviceItem devices[BUFFER_LEN];
int devices[BUFFER_LEN];//保存一个地址
}InputOpr,*PInputOpr;
void InitInputBuffer(PInputOpr opr);
//int putInputBuffer(PInputOpr opr,PDeviceItem data);
//int getInputBuffer(PInputOpr opr,PDeviceItem data);
int putInputBuffer(PInputOpr opr,int addr);
int getInputBuffer(PInputOpr opr,int *addr);
extern InputOpr g_InputOpr_485;
extern InputOpr g_InputOpr_232;
#endif // DEBUG
/*
int putInputBuffer(PInputOpr opr,PDeviceItem data)
{
pthread_mutex_lock(&mutex);
if(!isInputBufferFull(opr))
{
opr->devices[opr->write] = *data;
opr->write = (opr->write + 1) % BUFFER_LEN;
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_mutex_unlock(&mutex);
return -1;
}*/
int putInputBuffer(PInputOpr opr,int addr)
{
pthread_mutex_lock(&mutex);
if(!isInputBufferFull(opr))
{
opr->devices[opr->write] = addr;//消息的地址
opr->write = (opr->write + 1) % BUFFER_LEN;
pthread_mutex_unlock(&mutex);
return 0;
}
pthread_mutex_unlock(&mutex);
return -1;
}
/*
int getInputBuffer(PInputOpr opr,PDeviceItem data)
{
if(!isInputBufferEmpty(opr))
{
*data = opr->devices[opr->read];
opr->read = (opr->read + 1) % BUFFER_LEN;
return 0;
}
return -1;
}*/
int getInputBuffer(PInputOpr opr,int *addr)
{
if(!isInputBufferEmpty(opr))
{
//printf("addr 0x%x\n",opr->devices[opr->read]);
*addr = opr->devices[opr->read];
opr->read = (opr->read + 1) % BUFFER_LEN;
return 0;
}
return -1;
}