线程破解程序死循环

8 篇文章 0 订阅
最近用opencv+mfc做了一个简单的程序(点击button后,打开视频,另一个button关闭视频)。问题来了,读视频的程序是个死循环。怎么解。因此,应该考虑线程的问题了。让视频程序在线程里跑。

何为线程?

线程,有时被称为轻量级进程(Lightweight Process,LWP),是程序执行流的最小单元。一个标准的线程由线程ID,当前指令 指针(PC), 寄存器集合和 堆栈组成。另外,线程是进程中的一个实体,是被系统独立调度和分派的基本单位,线程自己不拥有系统资源,只拥有一点儿在运行中必不可少的资源,但它可与同属一个进程的其它线程共享进程所拥有的全部资源。一个线程可以创建和撤消另一个线程,同一进程中的多个线程之间可以并发执行。由于线程之间的相互制约,致使线程在运行中呈现出间断性。线程也有 就绪阻塞运行三种基本状态。就绪状态是指线程具备运行的所有条件,逻辑上可以运行,在等待处理机;运行状态是指线程占有处理机正在运行;阻塞状态是指线程在等待一个事件(如某个信号量),逻辑上不可执行。每一个程序都至少有一个线程,若程序只有一个线程,那就是程序本身。
线程是程序中一个单一的顺序控制流程。进程内一个相对独立的、可调度的执行单元,是系统独立调度和分派CPU的基本单位指 运行中的程序的调度单位。在单个程序中同时运行多个线程完成不同的工作,称为 多线程

 线程如何实现?

实际上可以这样简单的理解线程,它是CPU的调度单位.而一个线程是对应一个函数.所以别把一个线程想得太复杂,就只是执行个函数而已.只不过执行的时候是并行执行罢了.如果只是简单的几个线程不涉及使用共同的资源,没其他啥关联.就完全跟简单的执行一个函数类似.只是如果多个线程间关系复杂就会涉及到啥同步问题,那样就有很多复杂的细节性问题.

线程与函数

线程函数必须是全局函数,或者是类的静态成员函数,因为非静态成员函数有this指针,而在进程中无法访问此指针。

但是静态成员函数只能访问静态成员,解决此问题途径:

1. 就是在调用静态成员函数时将this指针作为参数传入,通过该指针访问非静态成员。

2. 不将线程函数定义为类的静态成员函数,而是定义为类的友元函数,这样函数线程也可以有类成员函数相同的权限。

开始有摄像头打开函数: 

bool CcamShowDlg::CameraOpen()
{
	
	if (capture.isOpened() == 0)
	{
		AfxMessageBox(_T("摄像头初始化失败"));
		return false;
	}
	while (1)
	{
		Mat frame;
		capture >> frame;
		imshow("VideoShow",frame);
		waitKey(30);
	}

	return false;
}


若直接在clickbutton下添加函数

void CcamShowDlg::OnBnClickedButtonCameraopen()
{
	// TODO:  在此添加控件通知处理程序代码
	CameraOpen();
	
}

点击button后程序进入了CameraOpen()的死循环。

因此创建一个线程函数来调用CameraOpen()。

void CcamShowDlg::OnBnClickedButtonCameraopen()
{
	// TODO:  在此添加控件通知处理程序代码
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadFunc,NULL);		
}
UINT CcamShowDlg::ThreadFunc(LPVOID lpParam)
{
	CameraOpen();
	return 0;
}

此时的CameraOpen()必须是类的静态成员函数

static bool CameraOpen();

若CameraOpen()不是静态成员函数。此时程序应变为:

UINT CcamShowDlg::ThreadFunc(LPVOID lpParam)
{
	CcamShowDlg *pObj = (CcamShowDlg *)lpParam;
	pObj->CameraOpen();
	return 0;
}

void CcamShowDlg::OnBnClickedButtonCameraopen()
{
	// TODO:  在此添加控件通知处理程序代码
	CWinThread* pThread;
	pThread = AfxBeginThread(ThreadFunc,this);		
}


友元函数

友元函数是指某些虽然不是类成员却能够访问类的所有成员的函数。类授予它的友元特别的访问权。通常同一个开发者会出于技术和非技术的原因,控制类的友元和成员函数(否则当你想更新你的类时,还要征得其它部分的拥有者的同意)。

形式

friend 类型名 友元函数名(形参表);

然后在类体外对友元函数进行定义,定义的格式和普通函数相同,但可以通过对象作为参数直接访问对象的私有成员

说明如下:

1)必须在类的说明中说明友元函数,说明时以关键字friend开头,后跟友元函数的函数原型,友元函数的说明可以出现在类的任何地方,包括在private和public部分;

2)注意友元函数不是类的成员函数,所以友元函数的实现和普通函数一样,在实现时不用"::"指示属于哪个类,只有成员函数才使用"::"作用域符号;

3)友元函数不能直接访问类的成员,只能访问对象成员,

4)友元函数可以访问对象的私有成员,但普通函数不行;

5)调用友元函数时,在实际参数中需要指出要访问的对象,

6)类与类之间的友元关系不能继承。

7)一个类的成员函数也可以作为另一个类的友元,但必须先定义这个类。

用法参见http://blog.csdn.net/insistgogo/article/details/6608672

 

 


 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值