使用多线程实现数据实时采集
2004-09-03 11:55
696 查看
我是做行业软件的所以经常会接触到对数据进行实时采集的问题。一般的问题是,一个线程读取数据,其他的线程对数据进行处理(如画出实时曲线,将数据存入文件等等)。这涉及到两方面问题.1,线程的同步问题—典型的生产者和消费者的问题;2,数据结构问题。即将采集的数据以什么形式存储并由消费者进行读取。
下面我将对这两个问题和大家一起探讨一下。相信大家对生产者消费者问题并不陌生。在读书的时候我们采用系统体提供的p,v解决,这是对同一临界区资源同时进行读写需要的保护措施,本工程使用缓冲队列,故不需要对临界区进行加锁 。马上我会实现双缓存的版本。在此版本中我会实现对临界区的加减锁。
读取的数据要存储到相应的数据结构中,可以有很多种选择,比如存成任务缓冲队列(以链表实现)其中大部分工程使用循环队列用于一写多读,写线程将数据写入队列,读线程从队列中读取。或者实现双缓存方法,即写线程写满一个缓存读线程来取数据同时写线程将数据写入另一个缓存。
具体的实现如下:
链表的节点声明如下:
typedef struct NODE
{
int Buffer[MAX_BUFFER_SIZE];
long Counters;
bool ReadEnable;
NODE * pNext;
}NODE;
其中数组Buffer[]用来存放采集数据。Counters用来描述有多少个读线程曾对节点进行访问。如果所有读线程都访问过此节点,即可将此节点删除!ReadEnable表示其节点是否可读。
链表的声明如下:
typedef struct LIST
{
NODE * pReadPtr;
NODE * pWritePtr;
NODE * pHeadPtr;
}LIST;
其中pReadPtr为指向可读节点的指针,pWritePtr为指向可写节点的指针。其中pReadPtr在pWritePtr的后面,也就是写指针不能超过读指针。pHeadPtr指向链表中第一个节点的指针。
我使用一个写线程两个读线程,也可以实现两个以上的读线程。朋友们可以试一下只需要修改list中Counters就行了。
DWORD WINAPI ReaderOne(void * pVoid);
DWORD WINAPI ReaderTwo(void * pVoid);
DWORD WINAPI WriterUnique(void * pVoid);
在WriterUnique我采用动态分配节点,同时模拟数据采集填充NODE的buffer数组。当然要对写线程进行加锁保护。在ReaderOne和ReaderTwo中对链表中的节点进行访问并显示在对话框中。
注意的问题:
1, 因为节点是动态分配内存,所以new之后一定要delete否则内存就会被程序慢慢吃掉
2,加锁之后一定要解锁否则就会引起死锁问题。
3,首先点击“启动写线程”然后点击“启动读线程 ”程序在退出之前点击“结束写线程“就可观察到执行效果。
有兴趣的朋友们可以索要源代码!我的mail是savage54321@hotmail.com
下面我将对这两个问题和大家一起探讨一下。相信大家对生产者消费者问题并不陌生。在读书的时候我们采用系统体提供的p,v解决,这是对同一临界区资源同时进行读写需要的保护措施,本工程使用缓冲队列,故不需要对临界区进行加锁 。马上我会实现双缓存的版本。在此版本中我会实现对临界区的加减锁。
读取的数据要存储到相应的数据结构中,可以有很多种选择,比如存成任务缓冲队列(以链表实现)其中大部分工程使用循环队列用于一写多读,写线程将数据写入队列,读线程从队列中读取。或者实现双缓存方法,即写线程写满一个缓存读线程来取数据同时写线程将数据写入另一个缓存。
具体的实现如下:
链表的节点声明如下:
typedef struct NODE
{
int Buffer[MAX_BUFFER_SIZE];
long Counters;
bool ReadEnable;
NODE * pNext;
}NODE;
其中数组Buffer[]用来存放采集数据。Counters用来描述有多少个读线程曾对节点进行访问。如果所有读线程都访问过此节点,即可将此节点删除!ReadEnable表示其节点是否可读。
链表的声明如下:
typedef struct LIST
{
NODE * pReadPtr;
NODE * pWritePtr;
NODE * pHeadPtr;
}LIST;
其中pReadPtr为指向可读节点的指针,pWritePtr为指向可写节点的指针。其中pReadPtr在pWritePtr的后面,也就是写指针不能超过读指针。pHeadPtr指向链表中第一个节点的指针。
我使用一个写线程两个读线程,也可以实现两个以上的读线程。朋友们可以试一下只需要修改list中Counters就行了。
DWORD WINAPI ReaderOne(void * pVoid);
DWORD WINAPI ReaderTwo(void * pVoid);
DWORD WINAPI WriterUnique(void * pVoid);
在WriterUnique我采用动态分配节点,同时模拟数据采集填充NODE的buffer数组。当然要对写线程进行加锁保护。在ReaderOne和ReaderTwo中对链表中的节点进行访问并显示在对话框中。
注意的问题:
1, 因为节点是动态分配内存,所以new之后一定要delete否则内存就会被程序慢慢吃掉
2,加锁之后一定要解锁否则就会引起死锁问题。
3,首先点击“启动写线程”然后点击“启动读线程 ”程序在退出之前点击“结束写线程“就可观察到执行效果。
有兴趣的朋友们可以索要源代码!我的mail是savage54321@hotmail.com
相关文章推荐
- linux系统下使用rsync实现网站数据实时同步备份
- 用S3C2410实现铁路数据实时采集系统
- 使用storm实现实时GPS数据客流特征分析系统:源码分析
- C# 实现 客户端 对实时数据的采集 上传至服务端;在服务端把保存到内存中;供WEB页面调用
- 使用HighCharts实现实时数据展示
- 用Delphi在工业控制和自动化实现多线程进行数据采集
- C#多线程使用webbrowser实现采集动态网页的爬虫机器人
- 编写一个聊天程序:有接收数据部分,和发数据的部分, 这两部分需要同时执行,使用多线程实现,一个控制接收,一个控制发送
- 使用GoldenGate实现MySQL到Oracle的数据实时同步
- 用Delphi在工业控制和自动化实现多线程进行数据采集
- C++多线程笔记:使用std::lock_guard实现对共享数据的保护
- PHP使用3种方法实现数据采集
- Android实现语音数据实时采集、播放
- flume实现kafka到hdfs实时数据采集 - 有负载均衡策略
- 使用HighCharts实现实时数据展示
- 2 C#串口或TCP远程采集数据 chart图表使用示例 保存数据到access数据库和每日.txt文件并实时显示各参数曲线
- 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)
- fpga+dp83848实现百兆网络高速数据实时采集
- 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)
- 使用Socket通信实现Silverlight客户端实时数据的获取(模拟GPS数据,地图实时位置)