Re: 中国人,你为什么不快乐?# Joke - 肚皮舞运动
k*t
1 楼
class SyncBuf {
public:
void Thread1();
void Thread2();
private:
typedef vector BufT;
volatile BufT buffer_;
Mutex mtx_; // controls access to buffer_
};
Inside a thread function, you simply use a LockingPtr to get
controlled access to the buffer_ member variable:
void SyncBuf::Thread1() {
LockingPtr lpBuf(buffer_, mtx_);
BufT::iterator i = lpBuf->begin();
for (; i != lpBuf->end(); ++i) {
... use *i ...
}
}
The code is very easy to write and understand — whenever you need to use
buffer_, you must create a LockingPtr pointing to it. Once you do that
, you have access to vector's entire interface.
The nice part is that if you make a mistake, the compiler will point it out:
void SyncBuf::Thread2() {
// Error! Cannot access 'begin' for a volatile object
BufT::iterator i = buffer_.begin();
// Error! Cannot access 'end' for a volatile object
for (; i != lpBuf->end(); ++i) {
... use *i ...
}
}
You cannot access any function of buffer_ until you either apply a const_
cast or use LockingPtr. The difference is that LockingPtr offers an ordered
way of applying const_cast to volatile variables.
LockingPtr is remarkably expressive. If you only need to call one function,
you can create an unnamed temporary LockingPtr object and use it directly:
unsigned int SyncBuf::Size() {
return LockingPtr(buffer_, mtx_)->size();
}
public:
void Thread1();
void Thread2();
private:
typedef vector
volatile BufT buffer_;
Mutex mtx_; // controls access to buffer_
};
Inside a thread function, you simply use a LockingPtr
controlled access to the buffer_ member variable:
void SyncBuf::Thread1() {
LockingPtr
BufT::iterator i = lpBuf->begin();
for (; i != lpBuf->end(); ++i) {
... use *i ...
}
}
The code is very easy to write and understand — whenever you need to use
buffer_, you must create a LockingPtr
, you have access to vector's entire interface.
The nice part is that if you make a mistake, the compiler will point it out:
void SyncBuf::Thread2() {
// Error! Cannot access 'begin' for a volatile object
BufT::iterator i = buffer_.begin();
// Error! Cannot access 'end' for a volatile object
for (; i != lpBuf->end(); ++i) {
... use *i ...
}
}
You cannot access any function of buffer_ until you either apply a const_
cast or use LockingPtr. The difference is that LockingPtr offers an ordered
way of applying const_cast to volatile variables.
LockingPtr is remarkably expressive. If you only need to call one function,
you can create an unnamed temporary LockingPtr object and use it directly:
unsigned int SyncBuf::Size() {
return LockingPtr
}