首先我们要明白为什么要学习线程,线程学习了有什么好处?
举一个很简单的例子MFC实现
在MFC里面添加一个按钮IDC_START
双击添加代码:
Sleep(9000);
然后编译运行看看
你会发现程序有9秒的“卡死”时间!
问题发现了,下面就来解决问题
进程与线程的概念就不讨论了 ,只要知道,
一般的 一个程序只有一个进程
一般的 一个进程只有一个主线程
一般的 一个进程有多个线程
这么多一般的不知道把我们搞晕木有
下面写一个在主对话框上面动态现实时间的例子来讲解线程
我们将用到一个函数:
创建线程函数
HANDLE CreateThread(
LPSECURITY_ATTRIBUTES lpThreadAttributes,
DWORD dwStackSize,
LPTHREAD_START_ROUTINE lpStartAddress,
LPVOID lpParameter,
DWORD dwCreationFlags,
LPDWORD lpThreadId);
该函数在其调用进程的进程空间里创建一个新的线程,并返回已建线程的句柄,其中各参数说明如下:
lpThreadAttributes:指向一个 SECURITY_ATTRIBUTES 结构的指针,该结构决定了线程的安全属性,一般置为 NULL;
dwStackSize:指定了线程的堆栈深度,一般都设置为0;
lpStartAddress:表示新线程开始执行时代码所在函数的地址,即线程的起始地址。一般情况为(LPTHREAD_START_ROUTINE)ThreadFunc,ThreadFunc 是线程函数名;
lpParameter:指定了线程执行时传送给线程的32位参数,即线程函数的参数;
dwCreationFlags:控制线程创建的附加标志,可以取两种值。如果该参数为0,线程在被创建后就会立即开始执行;如果该参数为CREATE_SUSPENDED,则系统产生线程后,该线程处于挂起状态,并不马上执行,直至函数ResumeThread被调用;
lpThreadId:该参数返回所创建线程的ID;
如果创建成功则返回线程的句柄,否则返回NULL。
首先 建立一个thread1_1的对话框
在 thread1_1Dlg.h 头文件里面 加入一个
一定要注意 这个函数需要在 累的外面申明,不然会出现错误的
然后 添加两个按钮
IDC_START 和 IDC_STOP
继续添加一个 静态文本控件 IDC_TIME
双击 两个按钮快速形成两个函数
添加下面代码
void CThread1_1Dlg::OnStart()
{
// TODO: Add your control notification handler code here
m_brun = true ; //使运行的值为真
hthread = CreateThread( NULL , 0 , (LPTHREAD_START_ROUTINE)threadfunc , NULL , 0 , &threadid );
((CButton*)GetDlgItem(IDC_START))->EnableWindow(false);
((CButton*)GetDlgItem(IDC_STOP))->EnableWindow(true);
}
void CThread1_1Dlg::OnStop()
{
// TODO: Add your control notification handler code here
m_brun = false ;
((CButton*)GetDlgItem(IDC_START))->EnableWindow(true);
((CButton*)GetDlgItem(IDC_STOP))->EnableWindow(false);
}
然后再 这两个函数的上面添加
func()函数的实现代码
void threadfunc()
{
CTime times;
CString str;
m_brun = true ;
while (m_brun)
{
times = CTime::GetCurrentTime();
str = times.Format("%H:%M:%S");
::SetDlgItemText( AfxGetMainWnd()->m_hWnd , IDC_TIME , str );
Sleep(1000);
}
}
在 文件的最上面 加入代码
bool m_brun;
这样就可以了
点击开始就可以动态显示 时间了
可能大家会说 用ontimer()函数也可以实现显示时间
但是我们是学习的线程
所以就用线程举例子了
下面是代码地址
免积分的
http://download.youkuaiyun.com/detail/midle110/4409017