文章目录
  1. 1. 引言
  2. 2. 功能概述
  3. 3. 代码实现
  4. 4. 结束语

引言

信号采样序列的生成与存储是雷达电子战系统仿真的前提。设计并采用存储高效、访问便捷、线程安全的信号存储器,对于提高系统的仿真时效性具有重要意义。结合实际性能需求,利用C++设计并实现了一个这样的信号存储器,可为开发类似功能模型提供参考。

功能概述

该信号存储器的主要功能概述如下

  • 由外部应用系统指定信号存储器的容量,以及信号采样点存储数据的具体格式;
  • 销毁该信号存储器时,执行相应的内存、线程等清理,确保无内存泄露隐患;
  • 按照FIFO(即“先入先出”)的原则,完成单个、一组信号数据的存储;
  • 依据传入的信号采样点时间选择区间,完成单个、一组信号数据的取出;
  • 清空信号存储器;
  • 判断信号存储器是否已满;
  • 判断信号存储器是否为空;
  • 获取信号存储器的容量,即该存储器可保存信号采样点的最大数目;
  • 获取信号存储器当前存储的信号采样点数目;
  • 确保信号存储器在进行信号采样点存储、取出时的线程安全。

代码实现

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
#ifndef CIRCLEBUFFER_H
#define CIRCLEBUFFER_H
//定义信号采样结构体
struct RADSIGSAMPLES
{
double TimeIndex; //时间戳,s
float Amplitude; //幅度值,V
RADSIGSAMPLES() : TimeIndex(0.0), Amplitude(0.0) {}
};
#include <vector>
using std::vector;
class CircleBuffer
{
public:
CircleBuffer(int MaxSize = 65535);
virtual ~CircleBuffer();
bool push(const RADSIGSAMPLES& ele);
bool push(const vector<RADSIGSAMPLES>& ele);
void clear();
bool pop(RADSIGSAMPLES &ele);
bool pop(vector<RADSIGSAMPLES> &ele, double tbegin, double tend);
bool empty();
bool full();
int count();
int GetSize();
private:
RADSIGSAMPLES *Arr;
int _l;
int _c;
int _size;
int _cnt;
HANDLE _mutex;
int conv(int i);
};
#endif //CIRCLEBUFFER_H
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#include "stdafx.h"
#include "CircleBuffer.h"
CircleBuffer::CircleBuffer(int MaxSize) : _size(MaxSize)
{
if(_size < 1) _size = 1;
Arr = new RADSIGSAMPLES[MaxSize];
_l = _c = _size - 1;
_cnt = 0;
_mutex = CreateMutex(NULL,FALSE,NULL);
}
CircleBuffer::~CircleBuffer()
{
delete []Arr;
Arr = NULL;
CloseHandle(_mutex);
}
int CircleBuffer::conv(int i)
{
return (i < _size) ? i : 0;
}
bool CircleBuffer::push(const RADSIGSAMPLES& ele)
{
if(_cnt < _size)
{
try
{
WaitForSingleObject(_mutex,INFINITE);
_l = conv(_l + 1);
Arr[_l] = ele;
_cnt++;
ReleaseMutex(_mutex);
return true;
}
catch (...)
{
ReleaseMutex(_mutex); //防止死锁
return false;
}
}
else return false;
}
bool CircleBuffer::push(const vector<RADSIGSAMPLES>& ele)
{
vector<RADSIGSAMPLES>::const_iterator SigIt;
try
{
WaitForSingleObject(_mutex, INFINITE);
for (SigIt = ele.begin(); SigIt != ele.end(); SigIt++)
{
_l = conv(_l + 1);
Arr[_l] = *SigIt;
_cnt++;
if (_cnt >= _size) break;
}
ReleaseMutex(_mutex);
return true;
}
catch (...)
{
ReleaseMutex(_mutex); //防止死锁
return false;
}
}
bool CircleBuffer::pop(RADSIGSAMPLES &ele)
{
if(_cnt == 0) return false;
else
{
try
{
WaitForSingleObject(_mutex,INFINITE);
_cnt--;
_c = conv(_c + 1);
ele = Arr[_c];
ReleaseMutex(_mutex);
return true;
}
catch (...)
{
ReleaseMutex(_mutex); //防止死锁
return false;
}
}
}
bool CircleBuffer::pop(std::vector<RADSIGSAMPLES> &ele, double tbegin, double tend)
{
ele.clear();
try
{
WaitForSingleObject(_mutex,INFINITE);
bool retFlag = false;
while (1)
{
if (_cnt == 0)
break;
if ( Arr[conv(_c + 1)].TimeIndex < tbegin)
{
_cnt--;
_c = conv(_c + 1);
}
if (Arr[conv(_c + 1)].TimeIndex < tend && Arr[conv(_c + 1)].TimeIndex >= tbegin)
{
_cnt--;
_c = conv(_c + 1);
ele.push_back(Arr[_c]) ;
}
if (Arr[conv(_c + 1)].TimeIndex >= tend)
{
retFlag = true;
break;
}
}
ReleaseMutex(_mutex);
return retFlag;
}
catch (...)
{
ReleaseMutex(_mutex);
return false;
}
}
int CircleBuffer::count()
{
return _cnt;
}
bool CircleBuffer::empty()
{
if(!_cnt) return true;
else return false;
}
bool CircleBuffer::full()
{
return (_cnt == _size) ? true : false;
}
int CircleBuffer::GetSize()
{
return _size;
}
void CircleBuffer::clear()
{
_l = _c = _size - 1;
_cnt = 0;
}

结束语

总结上述CircleBuffer的实现过程,做以下补充说明:

  1. 为了确保信号存储器在进行信号采样点存储、取出时的线程安全,在存储器内部设置了互斥量Mutex,确保了读写操作的互斥性;
  2. 在头文件中定义了记录数据采样点的结构,可以修改它来改变记录采样点的类型;
  3. 实现了单个采样点、多个采样点的存储、取出操作。

上述信号存储器的实现过程中包含了较为深刻的C/C++编程实践经验。这种存储器结构将大量地应用于雷达电子战建模仿真过程中,尤其是在进行并行程序设计时。

文章目录
  1. 1. 引言
  2. 2. 功能概述
  3. 3. 代码实现
  4. 4. 结束语