// MutexDemo.cpp : 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include //createMutex
#include
//预先声明类
class NormalArgs;
//定义类的成员变量要加名空间
typedef void (NormalArgs::*operatorFunc)();
class NormalArgs {
private:
int count = 65535;
public:
int getCount();
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();
};
//类的实现
int NormalArgs::getCount() {
return count;
}
void NormalArgs::addCount() {
count++;
}
void NormalArgs::decCount() {
count--;
}
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) {
//确保拥有互斥对象的线程对被保护资源的独自访问
DWORD d = WaitForSingleObject(mutexHandle, INFINITE);
/* 由于类的非静态成员函数中有一个隐形的this指针,因此,类的成员函数的指针和一般函数的指针的表现形式不一样。 类的静态成员函数采用与一般函数指针相同的调用方式,而受this指针的影响,类的非静态成员函数与一般函数指针是不兼容的。而且,不同类的this指针是不一样的,因此,指向不同类的非静态成员函数的指针也是不兼容的。指向类的非静态成员函数的指针,在声明时就需要添加类名。 所以(*func)()调用的是"一般函数的指针",而不能调用"指向类的成员函数的指针" */
(this->*func)();
//释放当前线程拥有的互斥对象,以使其它线程可以拥有互斥对象,对被保护资源进行访问
ReleaseMutex(mutexHandle);
}
}
void MutexArgs::addCount() {
operatorCount(&NormalArgs::addCount);
}
void MutexArgs::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();
}
int main()
{
NormalArgs *normalArgs = new NormalArgs();
MutexArgs *mutexArgs = new MutexArgs();
//_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 = 2;
LPTHREAD_START_ROUTINE lpStartAddresses[type] = { (LPTHREAD_START_ROUTINE)&NormalThreadFunc, (LPTHREAD_START_ROUTINE)&MutexThreadFunc };
LPVOID lpParameters[type] = { normalArgs, mutexArgs };
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]);
}
}
printf("normalArgs count=%d\n", normalArgs->getCount());
printf("mutexArgs count=%d\n", mutexArgs->getCount());
delete normalArgs;
delete mutexArgs;
system("pause");
return 0;
}