如何使用 CSingleLock 提供对此缓冲区的访问?
我有这两种方法用于线程独占访问 CMyBuffer
对象:
标头:
class CSomeClass
{
//...
public:
CMyBuffer & LockBuffer();
void ReleaseBuffer();
private:
CMyBuffer m_buffer;
CCriticalSection m_bufferLock;
//...
}
实现:
CMyBuffer & CSomeClass::LockBuffer()
{
m_bufferLock.Lock();
return m_buffer;
}
void CSomeClass::ReleaseBuffer()
{
m_bufferLock.Unlock();
}
用法:
void someFunction(CSomeClass & sc)
{
CMyBuffer & buffer = sc.LockBuffer();
// access buffer
sc.ReleaseBuffer();
}
- 我喜欢的是, 用户只需执行一项功能 调用并且只能访问缓冲区 锁定后。
- 我不知道什么 就像用户必须释放 明确地。
更新:Nick Meyer 和 Martin York 指出了这些额外的缺点:
- 用户能够释放锁,然后使用缓冲区。
- 如果在释放锁之前发生异常,缓冲区将保持锁定状态。
我想使用 CSingleLock
对象(或类似的东西)来完成此操作,当对象超出范围时,它会解锁缓冲区。
怎么可能呢?
I have these two methods for thread-exclusive access to a CMyBuffer
object:
Header:
class CSomeClass
{
//...
public:
CMyBuffer & LockBuffer();
void ReleaseBuffer();
private:
CMyBuffer m_buffer;
CCriticalSection m_bufferLock;
//...
}
Implementation:
CMyBuffer & CSomeClass::LockBuffer()
{
m_bufferLock.Lock();
return m_buffer;
}
void CSomeClass::ReleaseBuffer()
{
m_bufferLock.Unlock();
}
Usage:
void someFunction(CSomeClass & sc)
{
CMyBuffer & buffer = sc.LockBuffer();
// access buffer
sc.ReleaseBuffer();
}
- What I like about this is, that the
user has to make only one function
call and can only access the buffer
after having locked it. - What I don't
like is that the user has to release
explicitly.
Update: These additional disadvantages were pointed out by Nick Meyer and Martin York:
- The user is able to release the lock and then use the buffer.
- If an exception occurs before releasing the lock, the buffer remains locked.
I'd like to do it with a CSingleLock
object (or something similar), which unlocks the buffer when the object goes out of scope.
How could that be done?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
一种方法是使用 RAII:
One way to do this would be using RAII:
使用代表缓冲区的对象。
当这个对象初始化时获取锁,当它被销毁时释放锁。
添加强制转换运算符,以便可以在任何函数调用中使用它来代替缓冲区:
Use an object that represents the buffer.
When this obejct is initialized get the lock and when it is destroyed release the lock.
Add a cast operator so it can be used in place of the buffer in any function call:
恕我直言,如果您的目标是阻止用户仅在锁定时访问缓冲区,那么您将面临一场棘手的战斗。 考虑用户是否这样做:
为了允许用户访问缓冲区,您必须返回对缓冲区的引用,他们总是会犯错误,一直保留到释放锁为止。
也就是说,您也许可以执行以下操作:
使用如下:
这会强制用户将 CMyBuffer 对象包装在 CMySynchronizedBuffer 对象中,以便获取其任何变异方法。 由于它实际上并不通过返回引用来提供对底层 CMyBuffer 对象的访问,因此它不应该在锁释放后为用户提供任何可以保留和改变的内容。
IMHO, if your goal is to prevent the user from only accessing the buffer when it is locked, you're fighting a tricky battle. Consider if the user does:
In order to allow the user access to the buffer, you've got to return a reference to the buffer, which they can always make the mistake of holding on to until after the lock is released.
That said, you may be able to do something like this:
Use like:
This forces the user to wrap the CMyBuffer object in a CMySynchronizedBuffer object in order to get at any of its mutating methods. Since it doesn't actually provide access to the underlying CMyBuffer object by returning a reference, then it shouldn't give the user anything to hang onto and mutate after the lock is released.