win32 MFC 线程
来源:互联网 发布:gif编辑文字软件 编辑:程序博客网 时间:2024/06/05 02:58
CreateThread
参数1:NULL使用默认安全性,不可以被子线程继承,否则需要定义一个结构体将它的bInheritHandle成员初始化为TRUE
参数2:设置初始栈的大小,如果为0,那么默认将使用与调用该函数的线程相同的栈空间大小
参数3:指定线程运行处地址,即指向新线程开始执行代码的函数
参数4:附带参数
参数5:控制线程的附加标志,CREATE_SUSPEND(挂起状态,直到调用ResumeThread才被调用),为0则立即运行
参数6:线程ID,
返回线程句柄,HANDLE 类型
CloseHandle(线程句柄)//退出线程
SuspendThread(线程句柄)//暂停线程
ResuemThread(线程句柄)//恢复线程
ExitThread(可以为任意值)//终止自身线程,主要在线程执行函数中使用
TerminateThread(线程句柄,指定退出码)//返回0成功,否则非0,该函数虽然可以立刻终止线程,但不释放线程所占用的资源
//一般线程执行到线程函数的结尾时,系统会自动调用ExitThread 终止线程
GetExitCodeThread(线程句柄,线程码)//可调用此函数,进行判断是否终止线程了
TerminateProcess 强行终止进程
MFC 有两种线程
1:UI线程
AfxBeginThread(RUNTIME_CLASS(UI类型), 是否挂起或立即执行,堆栈大小,安全性);
2:工作线程(没有消息循环)
AfxBeginThread(执行线程函数地址,附带参数);
SuspendThread();//线程挂起,暂停
ResumeThread();//线程恢复,启动
线程同步:
1:临界区(CCriticalSection)只能在同一进程中,控制多个线程数据同步
UINT __cdecl CtestDlg::ThreadFun0(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_clsCriticalSection.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST1)))->AddString(str);p->m_clsCriticalSection.Unlock();//释放该同步对象Sleep(1000);}return false;}UINT __cdecl CtestDlg::ThreadFun1(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_clsCriticalSection.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST2)))->AddString(str);p->m_clsCriticalSection.Unlock();//释放该同步对象Sleep(1000);}return false;}CCriticalSection m_clsCriticalSection;//构造一个临界区对象m_pThread0 = AfxBeginThread(ThreadFun0, this); m_pThread1 = AfxBeginThread(ThreadFun1, this);
2:互诉量(CMutex)可以在多个进程中,控制多个线程数据同步
UINT __cdecl CtestDlg::ThreadFun0(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_clsMetex.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST1)))->AddString(str);p->m_clsMetex.Unlock();//释放该同步对象}return false;}UINT __cdecl CtestDlg::ThreadFun1(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_clsMetex.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST2)))->AddString(str);p->m_clsMetex.Unlock();//释放该同步对象}return false;}CMutex m_clsMetex;//构造互诉量对象(线程最初是否有权访问权,互诉量ID,安全属性)m_pThread0 = AfxBeginThread(ThreadFun0, this);m_pThread1 = AfxBeginThread(ThreadFun1, this);
3:事件(Event)
自动: CEvent m_clsEvent;
手动: CEent M_clsEvent(FALSE, TRUE);
UINT __cdecl CtestDlg::WordThreadFun1(LPVOID lpParam){CtestDlg *pDlg = (CtestDlg *)lpParam;CString str;while (pDlg->m_unSum < 20){//WaitForSingleObject(pDlg->m_Event, INFINITE);//设置等待状态pDlg->m_Event.Lock();//获得对该同步对象控制的资源的访问str.Format(_T("%d\r\n"), pDlg->m_unSum++);pDlg->m_List1.AddString(str);pDlg->m_Event.SetEvent();}return false;}UINT __cdecl CtestDlg::WordThreadFun2(LPVOID lpParam){CtestDlg *pDlg = (CtestDlg *)lpParam;CString str;while (pDlg->m_unSum < 20){//WaitForSingleObject(pDlg->m_Event, INFINITE);//设置等待状态pDlg->m_Event.Lock();//获得对该同步对象控制的资源的访问str.Format(_T("%d\r\n"), pDlg->m_unSum++);pDlg->m_List2.AddString(str);pDlg->m_Event.SetEvent();}return false;} CWinThread *pWordThread1; CWinThread *pWordThread2; CEvent m_Event; m_Event.SetEvent();//设置有信号 pWordThread1 = AfxBeginThread(WordThreadFun1, this); pWordThread2 = AfxBeginThread(WordThreadFun2, this); m_Event.Unlock();//释放对该同步对象的访问
4:信号量(Semaphore)
UINT __cdecl CtestDlg::ThreadFun0(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_pSemaphore.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST1)))->AddString(str);p->m_pSemaphore.Unlock();//释放该不同对象}return false;}UINT __cdecl CtestDlg::ThreadFun1(LPVOID lpParam){CtestDlg *p = (CtestDlg *)lpParam;CString str;while (p->m_unSum < 20){p->m_pSemaphore.Lock();//获得该同步对象的访问str.Format(_T("%d"), p->m_unSum++);((CListBox *)(p->GetDlgItem(IDC_LIST2)))->AddString(str);p->m_pSemaphore.Unlock();//释放该同步对象}return false;} CSemaphore m_pSemaphore;//构造一个信号量对象(线程数量值,信号量计数值,信号量ID,安全属性)m_pThread0 = AfxBeginThread(ThreadFun0, this);m_pThread1 = AfxBeginThread(ThreadFun1, this);
Win32 线程:
/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/当一个程序.exe(保存进程内存地址对象),运行时由系统调用,并存放在内核里;进程是不执行任何代码,它只是线程的容器;一个进程可包含多个线程,当系统创建一个进程时,会自动创建这个进程的主线程(第一个线程);/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*///CreateThread(安全属性(一般为NULL),线程栈内存大小,线程指定运行函数,线程指定运行函数形参,命令行形参,//控制线程标记(CREATE_SUSPENDED暂停,必须调用ResumeThread开始运行线程)如果是0线程立即运行,线程ID);HANDLE hthread1;hthread2 = CreateThread(NULL, 0, Fun1, NULL, 0, NULL);CloseHandle(hthread1);//关闭线程句柄Sleep(1000);//睡眠//线程处理函数DWORD WINAPI Fun2(LPVOID lpParameter){reutrn NULL;}/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/(线程同步)互诉对象//CreateMutex(安全属性(一般为NULL),互诉对象拥有者(TRUE创建这个互诉对象的线程获得该对象的所有权,//NULL不获得所有权, 互诉对象ID,)HANDLE hmutex;hmutex = CreateMutex(NULL,FALSE, NULL);//调用此函数获取互诉对象所有权(互诉对象句柄,间隔时间(INFINITE永远等待))有信号状态WaitForSingleObject(hmutex, INFINITE);ReleaseMutex(hmutex);//释放(权)互诉对象句柄/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*//*运行注意事项实例:1:主要是依靠线程,运行中来判断;2:线程结束时,是无法判断;3:在线程运行未结束时,进行判断是否还存在实例*/HANDLE hMutex;hMutex = CreateMutex(NULL, TRUE, L"test");if(hMutex){if(GetLastError() == ERROR_ALREADY_EXISTS){cout <<"已经有进程在运行了 ... " <<endl;return false;}}/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/(线程同步)事件对象//CreateEvent(安全属性(默认NULL),(TRUE)人工重置事件(FALSE)自动事件,(TRUE)有信号(FALSE)无信号,事件ID)//SetEvent(事件对象句柄);//设置有信号状态//ResetEvent(事件对象句柄);//设置无信号状态//备注:当时间对象初始化无信号状态时,可在线程开启信号状态,并在同步数据尾部关闭信号;//互诉对象和事件对象都是属于内核对象,利用内核对象进行线程同步时,速度较慢,但是利用互诉和事件对象,可以//在多个进程中的各个线程间进行同步;#include <iostream>#include <windows.h>using namespace std;int i = 100;HANDLE hEvent;DWORD WINAPI Fun1(LPVOID lpPrame){while(TRUE){//调用此函数获取互诉对象所有权(互诉对象句柄,间隔时间(INFINITE永远等待))有信号状态WaitForSingleObject(hEvent, INFINITE);if(i > 0){cout <<"Thread1 ___ " <<i-- <<endl;}elsebreak;SetEvent(hEvent);//开启有信号}return NULL;}DWORD WINAPI Fun2(LPVOID lpPram){while(TRUE){WaitForSingleObject(hEvent, INFINITE);if(i > 0){cout <<"Thread2 _______ " <<i-- <<endl;}elsebreak;SetEvent(hEvent);//开启有信号}return NULL;}int main(void){hEvent = CreateEvent(NULL, FALSE, FALSE, L"test");if(hEvent){if(ERROR_ALREADY_EXISTS == GetLastError())//是否有实例在运行{cout <<"已经有实例在运行了" <<endl;return NULL;}}SetEvent(hEvent);//开启有信号HANDLE hThread1;//线程对象HANDLE hThread2;//线程对象hThread1 = CreateThread(NULL, 0, Fun1, NULL, 0, NULL);//创建线程并返回线程句柄hThread2 = CreateThread(NULL, 0, Fun2, NULL, 0, NULL);//创建线程并返回线程句柄CloseHandle(hThread1);//关闭线程CloseHandle(hThread2);//关闭线程Sleep(4000);CloseHandle(hEvent);//关闭事件对象return false;}/*-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------*/(线程同步)关键代码块/临界区//CRITICAL_SECTION G_CS//EnterCriticalSection(&G_CS);//获取临界区所有权//LeaveCriticalSection(&G_CS);//释放临界区所有权//DeleteCriticalSection(&G_CS);//释放临界区对象//备注:临界区(关键代码段),工作在用户方式下,同步速度较快,但是使用临界区(关键代码段),很容易进入死锁,//因为在等待进入临界区(关键代码段)时无法设定超时值;//通常,在编写多线程程序时需要实现线程同步,首选临界区(关键代码段),在构造函数中(InitializeCriticalSection)//在析构函数中(DeleteCriticalSection),在调用EnterCriticalSection函数,在访问完后调用(LeaveCriticalSection);int G_SUN = 100;CRITICAL_SECTION G_CS;DWORD WINAPI Fun1(LPVOID lpParam){while(TRUE){EnterCriticalSection(&G_CS);if(G_SUN > 0){Sleep(2000);cout <<"Thread1 __ " <<G_SUN-- <<endl;LeaveCriticalSection(&G_CS);}else{LeaveCriticalSection(&G_CS);break;}}return false;}DWORD WINAPI Fun2(LPVOID lpParam){while(TRUE){EnterCriticalSection(&G_CS);if(G_SUN > 0){Sleep(1);cout <<"Thrad2 _____ " <<G_SUN-- <<endl;LeaveCriticalSection(&G_CS);}else{LeaveCriticalSection(&G_CS);break;}//LeaveCriticalSection(&G_CS);}return false;}int main(void){HANDLE hThread1;HANDLE hThread2;int param;InitializeCriticalSection(&G_CS);hThread1 = CreateThread(NULL, 0, Fun1, NULL, 0, NULL);hThread2 = CreateThread(NULL, 0, Fun2, NULL, 0, NULL);CloseHandle(hThread1);CloseHandle(hThread2);Sleep(4000);DeleteCriticalSection(&G_CS);cin >>param;return false;}
- win32 MFC 线程
- Win32下的线程和MFC的线程实现
- Win32 线程
- Win32线程
- 2:MFC和Win32
- MFC和Win32
- Win32 and MFC
- Win32 MFC的关系
- MFC和Win32
- MFC和Win32
- WIN32 API与MFC
- MFC和Win32
- ATL/CLR/MFC/Win32
- MFC&WIN32比较
- 关于WIN32,MFC,数据库
- Win32开发MFC程序
- mfc与win32区别
- MFC VS Win32
- C++基础课 —>vi编辑器与C入门Demo
- C-inline函数
- Box2D 接触监听器和过滤器
- iOS UIViewController 对内存警告的处理经验
- 正则表达式,不包含 字符串,regular expression
- win32 MFC 线程
- 闲着没事,默写个 dijkstra 算法
- 第二周作业
- wmap搭建————自己记录以备以后使用
- Sina微博应用开发指南
- ZOJ-2730
- 微软面试100题
- java SE 集合(四)
- poj 2092 Grandpa is Famous