// MutexDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <Windows.h>//createMutex
#include <process.h>
//预先声明类
class NormalArgs;
//定义类的成员变量要加名空间(且只能在全局范围定义,不能在类中定义)
typedef void (NormalArgs::*operatorFunc)();
class NormalArgs {
private:
WORD wCount = 65535;
DWORD dwCount = 65535;
double doubleCount = 0;
public:
void getCountStr(char *str, size_t size);
void addCount();
void decCount();
};
class MutexArgs : public NormalArgs {
private:
HANDLE mutexHandle = NULL;
public:
MutexArgs();
~MutexArgs();
protected:
void operatorCount(operatorFunc func);
public:
void addCount();
void decCount();
};
class CriticalSectionArgs : public NormalArgs {
private:
CRITICAL_SECTION cs;
public:
CriticalSectionArgs();
~CriticalSectionArgs();
protected:
void operatorCount(operatorFunc func);
public:
void addCount();
void decCount();
};
//类的实现
void NormalArgs::getCountStr(char *str, size_t size) {
sprintf_s(str, size, "wCount=%d, dwCount=%ld, doubleCount=%lf\n", wCount, dwCount, doubleCount);
}
void NormalArgs::addCount() {
wCount++;
dwCount += 100;
doubleCount += 0.1;
}
void NormalArgs::decCount() {
wCount--;
dwCount -= 100;
doubleCount -= 0.1;
}
MutexArgs::MutexArgs() {
/*
CreateMutex作用是找出当前系统是否已经存在指定进程的实例。如果没有则创建一个互斥体
WINBASEAPI _Ret_maybenull_ HANDLE WINAPI CreateMutexW(
_In_opt_ LPSECURITY_ATTRIBUTES lpMutexAttributes,
_In_ BOOL bInitialOwner,
_In_opt_ LPCWSTR lpName
);
*/
LPSECURITY_ATTRIBUTES lpMutexAttributes = NULL;
BOOL bInitialOwner = FALSE;
LPCWSTR lpName = NULL;
//创建一个匿名互斥对象
mutexHandle = CreateMutex(lpMutexAttributes, bInitialOwner, lpName);
}
MutexArgs::~MutexArgs() {
if (mutexHandle != NULL) {
//销毁互斥对象,释放资源
CloseHandle(mutexHandle);
}
}
void MutexArgs::operatorCount(operatorFunc func) {
if (mutexHandle != NULL) {
/*
确保拥有互斥对象的线程对被保护资源的独自访问
WINBASEAPI DWORD WINAPI WaitForSingleObject(
_In_ HANDLE hHandle,
_In_ DWORD dwMilliseconds
);
WAIT_ABANDONED 0x00000080L
WAIT_OBJECT_0 0x00000000L
WAIT_TIMEOUT 0x00000102L
WAIT_FAILED 0xFFFFFFFF
*/
DWORD event = WaitForSingleObject(mutexHandle, INFINITE);
/*
由于类的非静态成员函数中有一个隐形的this指针,因此,类的成员函数的指针和一般函数的指针的表现形式不一样。
类的静态成员函数采用与一般函数指针相同的调用方式,而受this指针的影响,类的非静态成员函数与一般函数指针是不兼容的。而且,不同类的this指针是不一样的,因此,指向不同类的非静态成员函数的指针也是不兼容的。指向类的非静态成员函数的指针,在声明时就需要添加类名。
所以(*func)()调用的是"一般函数的指针",而不能调用"指向类的成员函数的指针"
*/
(this->*func)();
//释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问
ReleaseMutex(mutexHandle);
}
}
void MutexArgs::addCount() {
operatorCount(&NormalArgs::addCount);
}
void MutexArgs::decCount() {
operatorCount(&NormalArgs::decCount);
}
CriticalSectionArgs::CriticalSectionArgs() {
//初始化"临界区对象"
InitializeCriticalSection(&cs);
}
CriticalSectionArgs::~CriticalSectionArgs() {
//删除"临界区对象"
DeleteCriticalSection(&cs);
}
void CriticalSectionArgs::operatorCount(operatorFunc func) {
//进入"临界区"
EnterCriticalSection(&cs);
(this->*func)();
//离开"临界区"
LeaveCriticalSection(&cs);
}
void CriticalSectionArgs::addCount() {
operatorCount(&NormalArgs::addCount);
}
void CriticalSectionArgs::decCount() {
operatorCount(&NormalArgs::decCount);
}
void NormalThreadFunc(LPVOID lpParameter) {
NormalArgs *normalArgs = (NormalArgs *)lpParameter;
normalArgs->addCount();
Sleep(1);
normalArgs->decCount();
}
void MutexThreadFunc(LPVOID lpParameter) {
MutexArgs *mutexArgs = (MutexArgs *)lpParameter;
mutexArgs->addCount();
Sleep(1);
mutexArgs->decCount();
}
void CriticalSectionThreadFunc(LPVOID lpParameter) {
CriticalSectionArgs *criticalSectionArgs = (CriticalSectionArgs *)lpParameter;
criticalSectionArgs->addCount();
Sleep(1);
criticalSectionArgs->decCount();
}
int main()
{
NormalArgs *normalArgs = new NormalArgs();
MutexArgs *mutexArgs = new MutexArgs();
CriticalSectionArgs *criticalSectionArgs = new CriticalSectionArgs();
//_beginthreadex();
/*
#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_APP)
WINBASEAPI _Ret_maybenull_ HANDLE WINAPI CreateThread(
_In_opt_ LPSECURITY_ATTRIBUTES lpThreadAttributes,
_In_ SIZE_T dwStackSize,
_In_ LPTHREAD_START_ROUTINE lpStartAddress,
_In_opt_ __drv_aliasesMem LPVOID lpParameter,
_In_ DWORD dwCreationFlags,
_Out_opt_ LPDWORD lpThreadId
);
*/
LPSECURITY_ATTRIBUTES lpThreadAttributes = NULL;
SIZE_T dwStackSize = 0;
DWORD dwCreationFlags = 0;
LPDWORD lpThreadId = NULL;
const int THREAD_HANDLE_SIZE = 1000;
HANDLE threadHandles[THREAD_HANDLE_SIZE];
const int type = 3;
LPTHREAD_START_ROUTINE lpStartAddresses[type] = { (LPTHREAD_START_ROUTINE)&NormalThreadFunc, (LPTHREAD_START_ROUTINE)&MutexThreadFunc, (LPTHREAD_START_ROUTINE)&CriticalSectionThreadFunc };
LPVOID lpParameters[type] = { normalArgs, mutexArgs, criticalSectionArgs };
for (int i = 0; i < type; i++) {
for (int j = 0; j < THREAD_HANDLE_SIZE; j++) {
threadHandles[j] = CreateThread(lpThreadAttributes, dwStackSize, lpStartAddresses[i], lpParameters[i], dwCreationFlags, lpThreadId);
}
for (int j = 0; j < THREAD_HANDLE_SIZE; j++) {
//等待一个线程结束运行
WaitForSingleObject(threadHandles[j], INFINITE);
CloseHandle(threadHandles[j]);
}
}
const int BUFF_SIZE = 255;
char normalCountStr[BUFF_SIZE];
char mutexCountStr[BUFF_SIZE];
char criticalSectionCountStr[BUFF_SIZE];
normalArgs->getCountStr(normalCountStr, BUFF_SIZE);
mutexArgs->getCountStr(mutexCountStr, BUFF_SIZE);
criticalSectionArgs->getCountStr(criticalSectionCountStr, BUFF_SIZE);
printf(normalCountStr);
printf(mutexCountStr);
printf(criticalSectionCountStr);
delete normalArgs;
delete mutexArgs;
delete criticalSectionArgs;
system("pause");
return 0;
}
C/C++ Windows API——多线程加锁与临界区域
最新推荐文章于 2024-10-07 19:17:25 发布