您的位置:首页 > 其它

MFC(学习笔记) - 多线程同步

2016-04-24 18:19 302 查看

一、win32线程创建与互斥

创建线程

HANDLE WINAPI CreateThread(
_In_opt_  LPSECURITY_ATTRIBUTES  lpThreadAttributes,
_In_      SIZE_T                 dwStackSize,
_In_      LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_  LPVOID                 lpParameter,
_In_      DWORD                  dwCreationFlags,
_Out_opt_ LPDWORD                lpThreadId
);


参数介绍:

1、线程安全属性,一般为NULL

2、线程栈大小:一般为0,取默认大小

3、线程的函数名:顾名思义,如果为类内的函数,则设为static即可

4、线程的参数:可以传递一个结构体指针,没有则为NULL

5、创建的标记:一般设为0

6、线程的ID:如非必须,设为NULL

互斥锁

HANDLE WINAPI CreateMutex(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_     BOOL                  bInitialOwner,
_In_opt_ LPCTSTR               lpName
);


参数介绍:

1、互斥锁安全属性:一般为NULL

2、互斥锁默认是否有信号:一般为FALSE,表示无人拥有此信号,TRUE表示信号已被人拥有,不可再获取

3、互斥锁名称:一般为NULL,由于此锁为内核对象,进程间互斥的话,需要命名

注:互斥锁,谁拥有,谁释放;多次拥有,需要多次释放;谁创建时,参数为TRUE,谁拥有;

卖票例子:

int ticket = 10;
HANDLE hMutex;

DWORD WINAPI Thread1(LPVOID param) {
while (TRUE)
{
WaitForSingleObject(hMutex, INFINITE);
Sleep(500);
if (ticket > 0)
cout << "线程1:" << ticket-- << endl;
else
break;
ReleaseMutex(hMutex);

}
return TRUE;
}
DWORD WINAPI Thread2(LPVOID param) {
while (TRUE)
{
WaitForSingleObject(hMutex, INFINITE);
Sleep(500);
if (ticket > 0)
cout << "线程2:" << ticket-- << endl;
else
break;
ReleaseMutex(hMutex);
}
return TRUE;
}
int main()
{
HANDLE hTread1 = CreateThread(NULL, 0, Thread1, NULL,0, NULL);
HANDLE hTread2 = CreateThread(NULL, 0, Thread2, NULL,0, NULL);
CloseHandle(hTread1);
CloseHandle(hTread2);
hMutex = CreateMutex(NULL, FALSE, NULL);
getchar();
return 0;
}

注:MFC中封装了CMutex类

#include "afxmt.h"
CMutex mt;
mt.Lock();
mt.Unlock();


二、内核对象——事件

HANDLE WINAPI CreateEvent(
_In_opt_ LPSECURITY_ATTRIBUTES lpEventAttributes,
_In_     BOOL                  bManualReset,
_In_     BOOL                  bInitialState,
_In_opt_ LPCTSTR               lpName
);


参数介绍:

1、事件安全属性:一般为NULL,即默认

2、是否人工重置:TRUE代表由人工重置为初始信号,FALSE代表自动重置为初始信号

3、事件的初始信号:TRUE表示有信号,FALSE表示无信号

4、事件的名称:与上面的mutex一样

同样的卖票例子:

// ThreadTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

int ticket = 10;
HANDLE hEvent;

DWORD WINAPI Thread1(LPVOID param) {
while (TRUE)
{
WaitForSingleObject(hEvent, INFINITE);
Sleep(500);
if (ticket > 0)
cout << "线程1:" << ticket-- << endl;
else
break;
SetEvent(hEvent);

}
return TRUE;
}
DWORD WINAPI Thread2(LPVOID param) {
while (TRUE)
{
WaitForSingleObject(hEvent, INFINITE);
Sleep(500);
if (ticket > 0)
cout << "线程2:" << ticket-- << endl;
else
break;
SetEvent(hEvent);
}
return TRUE;
}
int main()
{
HANDLE hTread1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
HANDLE hTread2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);
CloseHandle(hTread1);
CloseHandle(hTread2);
hEvent = CreateEvent(NULL,FALSE, FALSE, NULL);
SetEvent(hEvent);
getchar();
return 0;
}


三、临界区

一共四个函数

void WINAPI InitializeCriticalSection(
_Out_ LPCRITICAL_SECTION lpCriticalSection
);


void WINAPI EnterCriticalSection(
_Inout_ LPCRITICAL_SECTION lpCriticalSection
);


void WINAPI LeaveCriticalSection(
_Inout_ LPCRITICAL_SECTION lpCriticalSection
);


void WINAPI DeleteCriticalSection(
_Inout_ LPCRITICAL_SECTION lpCriticalSection
);
卖票的例子:

// ThreadTest.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"

int ticket = 10;
CRITICAL_SECTION g_cs;

DWORD WINAPI Thread1(LPVOID param) {
while (TRUE)
{
EnterCriticalSection(&g_cs);
if (ticket > 0)
cout << "线程1:" << ticket-- << endl;
else
break;
LeaveCriticalSection(&g_cs);
Sleep(500);
}
return TRUE;
}
DWORD WINAPI Thread2(LPVOID param) {
while (TRUE)
{
EnterCriticalSection(&g_cs);
if (ticket > 0)
cout << "线程2:" << ticket-- << endl;
else
break;
LeaveCriticalSection(&g_cs);
Sleep(500);
}
return TRUE;
}
int main()
{
HANDLE hTread1 = CreateThread(NULL, 0, Thread1, NULL, 0, NULL);
HANDLE hTread2 = CreateThread(NULL, 0, Thread2, NULL, 0, NULL);
CloseHandle(hTread1);
CloseHandle(hTread2);
InitializeCriticalSection(&g_cs);
getchar();
DeleteCriticalSection(&g_cs);
return 0;
}


注:c++封装好的临界区类critical_section,简单好用如下:

#include "concrt.h"
using namespace concurrency;
critical_section g_cs;
g_cs.lock();
g_cs.unlock();
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: