# 多线程编程—LabWindows/CVI(新手自学上路,望各位大佬可以指点江山,激昂文字。求指导!!!)

程序描述:运用一个线程将数据存储到安全队列中,另一个线程来读取数据。
 

运行效果如下图:

                                                                                              图1:程序运行界面

面和控件属性如下:

表1:面板和控件属性
变量名控件类型控件属性以及功能
STRIPCHARTStrip Chart功能:显示将读取到的数据
TEXTBOXText Box功能:显示写入数据线程结果
TEXTBOX_2Text Box功能:显示读取数据线程结果
READCommand Button

功能:开起读取数据线程

回调函数:read

WRITECommand Button

功能:开起写入数据线程

回调函数:write

READ_STOPCommand Button

功能:停止读取数据线程

回调函数:read_stop

WRITE_STOPCommand Button

功能:停止写入数据线程

回调函数:write_stop

LED_READRound LED功能:写入数据线程开启时亮起
LED_WRITERound LED功能:读取数据线程开启时亮起

代码如下:

#include <ansi_c.h>
#include <utility.h>
#include <cvirte.h>		
#include <userint.h>
#include "Thread1.h"

static int panelHandle;

int queue;

int qr = 0;   // 开启、关闭线程的标志
int qw = 0;

int functionIdRead;
int funcTionIdWrite;

int CVICALLBACK readThreadFunction (void *functionData); // 回调函数
int CVICALLBACK writeThreadFunction (void *functionData);

int main (int argc, char *argv[])
{
	if (InitCVIRTE (0, argv, 0) == 0)
		return -1;	/* out of memory */
	if ((panelHandle = LoadPanel (0, "Thread1.uir", PANEL)) < 0)
		return -1;
	if ((CmtNewTSQ(1, sizeof(double), OPT_TSQ_DYNAMIC_SIZE, &queue)) < 0 )	   // 定义安全队列
		return -1;
	DisplayPanel (panelHandle);
	RunUserInterface ();  

	CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, readThreadFunction, NULL, &functionIdRead); // 读线程
	CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, writeThreadFunction, NULL, &funcTionIdWrite); // 写线程

	CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionIdRead, 0);	   // 倾向于防止死锁
	CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, funcTionIdWrite, 0);

	
	CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, functionIdRead);  // 释放线程
	CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, funcTionIdWrite);
	
	DiscardPanel (panelHandle);
	return 0;
}

int CVICALLBACK read (int panel, int control, int event,
					  void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			if (qr == 1) break; // 防止第二次点击按钮 又重新建立一个线程
			qr = 1;
			CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, readThreadFunction, NULL, &functionIdRead); // 读线程
			break;
	}
	return 0;
}

int CVICALLBACK write (int panel, int control, int event,
					   void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			if (qw == 1) break; 
			qw = 1;
			CmtScheduleThreadPoolFunction (DEFAULT_THREAD_POOL_HANDLE, writeThreadFunction, NULL, &funcTionIdWrite); // 写线程
			break;
	}
	return 0;
}

int CVICALLBACK quitsys (int panel, int control, int event,
						 void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			qr = 0;
			qw = 0;
			QuitUserInterface (0);
			break;
	}
	return 0;
}

int CVICALLBACK read_stop (int panel, int control, int event,
						   void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{
		case EVENT_COMMIT:
			qr = 0;
			SetCtrlVal (panelHandle, PANEL_LED_READ, 0); 
			//if(qr == 1 ){
			//	CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, functionIdRead, OPT_TP_PROCESS_EVENTS_WHILE_WAITING); 
			//	CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, functionIdRead);
			//}
			break;
	}
	return 0;
}

int CVICALLBACK write_stop (int panel, int control, int event,
							void *callbackData, int eventData1, int eventData2)
{
	switch (event)
	{																			    
		case EVENT_COMMIT:
			qw = 0;
			SetCtrlVal (panelHandle, PANEL_LED_WRITE, 0);
			//if(qw == 1){
			//	CmtWaitForThreadPoolFunctionCompletion (DEFAULT_THREAD_POOL_HANDLE, funcTionIdWrite, OPT_TP_PROCESS_EVENTS_WHILE_WAITING);
			//	CmtReleaseThreadPoolFunctionID (DEFAULT_THREAD_POOL_HANDLE, funcTionIdWrite); 
			//}

			break;
	}
	return 0;
}

int CVICALLBACK readThreadFunction (void *functionData)
{
	int items = 0;
	double array[1] = {0};
	char c[100];
	SetCtrlVal (panelHandle, PANEL_LED_READ, 1); 
	while(qr){
		CmtGetTSQAttribute(queue,ATTR_TSQ_ITEMS_IN_QUEUE,&items);
		if (items)
		{
			CmtReadTSQData (queue, array, 1, TSQ_INFINITE_TIMEOUT, NULL);
			PlotStripChart(panelHandle, PANEL_STRIPCHART, array, 1, 0, 0, VAL_DOUBLE);
			sprintf(c,"成功将 %f 读出队列\n",array[0]);
			SetCtrlVal (panelHandle, PANEL_TEXTBOX_2, c);
		}
	//	Delay(1);
	}
	return 0;
}

int CVICALLBACK writeThreadFunction (void *functionData)
{
	double a = 0;
	double array[1] = {0};
	char c[100];
	SetCtrlVal (panelHandle, PANEL_LED_WRITE, 1); 
	while(qw){
		a ++;
		sprintf(c,"成功将 %f 写入队列\n",a);
		SetCtrlVal (panelHandle, PANEL_TEXTBOX, c);
		array[0] = a;
		CmtWriteTSQData (queue, array, 1, TSQ_INFINITE_TIMEOUT, NULL);
		Delay(1);
	}
	return 0;
}

 

  • 0
    点赞
  • 19
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值