主要程序框图如图3所示,在循环开始前,使用“获取队列引用”函数创建消息队列。生产者循环使用“元素入队列”函数向队列中添加数据。消费者循环使用“元素出队列”函数从队列中获取消息并移除数据。
该设计模式允许消费者循环以固有速度采集信号的同时,生产者循环完成对用户界面的响应,生产者循环中采用事件结构,事件结构的延时时间为100 ms,采用轮询操作,处理用户界面各个控件的响应,对信号采集进行实时控制,同时为了不影响消费者循环中信号采集的连续性,并不是每一个用户事件都通过队列产生消息,通知消费者循环重新配置信号采集,只有在声卡配置参数(采样点数、采样率)发生改变时,生产者循环使用“发送通知”函数产生消息,以便通过“等待通知”函数通知消费者循环。
消费者循环内部是状态机结构,在第一次循环时进入“SetUp”分支,进行声卡的初始化配置,从下次循环开始,在其他控件发生改变而有关声卡配置的参数不发生变化时,生产者循环不会产生消息队列,消费者循环中在“daq”分支和“Wait”分支间进行,“Wait”分支仅检查消息队列中是否有消息,如果没有转“daq”分支进行数据采集,而不会进入声卡配置的“SetUp”分支,这样不仅保证了独立的采集过程不受影响,而且由用户界面引起的任何延时(如显示对话框)都不会导致采集过程的循环操作产生延时,从而保证采集音频信号的连续性。
在用户改变声卡配置参数发生时,生产者循环响应该事件,“元素入队列”函数向队列中添加消息,消费者循环“Wait”分支中的“元素出队列”函数从队列中移出消息,在下次循环时进入“Setup”分支进行声卡参数配置,然后转入“daq”分支继续进行信号采集。在“daq”分支中除进行数据采集外,还对信号进行功率谱分析,并将信号保存在一个硬盘文件中。
通过大量实验发现采用生产者/消费者设计模式设计的音频信号采集系统能够有效避免在采集过程中出现的声音中断和失真现象,较之以前基于其他模式的设计有一定的优势。
3 结 语
在LabVIEW程序设计过程中,并行循环之问的数据传递必须进行妥善处理,否则就会出现死循环等预想不到的错误。该文介绍的生产者/消费者设计模式不仅使并行循环间传递数据的逻辑关系更加简洁明了,使得程序的修改维护更加方便,而且大大提高了程序运行的效率。本文只是利用一个简单的实时控制的连续音频信号采集系统介绍了此模式的应用,阐明了这种设计模式的思想,在用LabVIEW设计如网络通信程序等要求准确且响应速度快的实时控制程序时,生产者/消费者模式有很好的借鉴意义。