[并发并行]_[初级]_[C++实现synchronized方式的对象锁]

本文介绍了一种名为AALock的类,它提供了一种类似于synchronized关键字的功能,用于对对象进行加锁。通过使用一个map进行object->mutex的映射,实现了线程安全的锁操作,从而避免了全局变量的使用,提高了代码的可维护性和安全性。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

场景:

1. 多线程程序, 数据如果在多线程间共享时, 比如数组, 基本都是需要加锁来保证安全,正确性. std库的数据结构类,如std::vector不是线程安全的, 所以读写时必须上锁.

2. objc,Java可以用sychronized来对对象加锁, 使能安全访问对象, 如果不加锁, 大多数情况下程序会崩溃.

3. 问题是无论是用 pthread_mutex_t 还是用CriticalSection, 都需要额外创建一个mutex和section来进行加锁,这样会增加很多全局变量

(需要在不同的源代码里使用锁,只能是全局变量), 使用不方便还容易出错.

4. 这里设计了一个AALock类, 功能类似synchronize 关键字, 对对象加锁. 本质就是用一个map来进行object->mutex的映射加锁.

5. pthread win32 也可以换成CriticalSection, 自己改吧.

aa_lock.h

#ifndef __AA_LOCK_H
#define __AA_LOCK_H

class  AALock
{
public:
	AALock(void* object);
	~AALock();

	static void GLock(void* object);
	static void GUnLock(void* object);

private:
	void* lock_object_;
};

#endif

aa_lock.cpp

#include "aa_lock.h"
#include "pthread.h"
#include <map>

typedef void* LockObject;
// 重点是这里,用map来作为mutex的映射,虽然会损失点性能,但是使用方便.
static std::map<void*,pthread_mutex_t> gLockObject;
pthread_mutex_t gMapMutex = NULL;

class AALockInternal
{
public:
	AALockInternal()
	{
		pthread_mutex_init(&gMapMutex,NULL);	
	}
	~AALockInternal()
	{
		pthread_mutex_destroy(&gMapMutex);
	}
};

static AALockInternal gLockInternal;

AALock::AALock(void* object)
{
	lock_object_ = object;
	GLock(object);
}

AALock::~AALock()
{
	GUnLock(lock_object_);
}

void AALock::GLock(void* object)
{
	pthread_mutex_lock(&gMapMutex);
	pthread_mutex_t lock = NULL;
	if(gLockObject.find(object)!=gLockObject.end())
	{
		lock = gLockObject[object];
	}else
	{
		pthread_mutex_t temp = NULL;
		pthread_mutex_init(&temp,NULL);
		gLockObject[object] = temp;
		lock = temp;
	}
	pthread_mutex_unlock(&gMapMutex);
	
	pthread_mutex_lock(&lock);
}

void AALock::GUnLock(void* object)
{
	pthread_mutex_lock(&gMapMutex);
	pthread_mutex_t lock = NULL;
	lock = gLockObject[object];
	pthread_mutex_unlock(&gMapMutex);

	pthread_mutex_unlock(&lock);
}


test.cpp

#include "pthread.h"

#include <stdlib.h>
#include <iostream>
#include <stdint.h>
#include <assert.h>
#include <string>
#include <vector>
#include "aa_lock.h"

static const int gMaxCountTime = 10000;
static const int gTextThreadNum = 100;
static pthread_t ts[gTextThreadNum];
static int64_t gCount = 0;
static std::vector<int> gCountArray;

void* StartPthread(void* data)
{
	for (int i = 0; i < gMaxCountTime; ++i)
	{
		// 去掉锁的话,下边的assert随时crash.
		// 可对对象加锁,类似objc或Java的同步关键字sychronized
		AALock::GLock(&gCount);
		++gCount;
		AALock::GUnLock(&gCount);

		// 去掉锁,push_back随时崩溃,因为vector并不是线程安全的.
		AALock::GLock(&gCountArray);
		gCountArray.push_back(i);
		AALock::GUnLock(&gCountArray);
	}

	return NULL;
}

void TestAALock()
{
	for (int i = 0; i < gTextThreadNum; ++i)
	{
		pthread_create(&ts[i],NULL,StartPthread,NULL);
	}

	for (int i = 0; i < gTextThreadNum; ++i)
	{
		pthread_join(ts[i],NULL);		
	}

	std::cout << "gCount: " << gCount << std::endl;
	assert(gCount == gMaxCountTime*gTextThreadNum);

	std::cout << "gCountArray size: " << gCountArray.size() << std::endl; 
	assert(gCount == gCountArray.size());
}

int main(int argc, char const *argv[])
{
	
	for (int i = 0; i < 10; ++i)
	{
		TestAALock();
		gCount = 0;
		gCountArray.clear();
	}
	

	return 0;
}


输出:

C:\Users\apple2\Desktop\test>test
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000
gCount: 1000000
gCountArray size: 1000000


完整项目下载地址:

http://download.youkuaiyun.com/detail/infoworld/9327825


 

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Peter(阿斯拉达)

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值