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;}













0 0
原创粉丝点击