我有一个多线程应用程序,必须经常读取一些数据,偶尔会更新数据.现在,互斥锁可以保持对数据安全的访问,但是它很昂贵,因为我希望多个线程能够同时读取,并且只在需要更新时将其锁定(更新线程可以等待其他线程完成) .
我认为这是boost::shared_mutex应该做的,但我不清楚如何使用它,并没有找到一个明确的例子.
有没有人有一个我可以用来开始的简单例子?
我已经使用Boost C++库很长一段时间了.我非常喜欢用于网络编程的Boost Asio C++库.然而,我被介绍到另外两个库:POCO和自适应通信环境(ACE)框架.我想知道每个人的好坏.
我有两个线程在运行.他们共享一个阵列.其中一个线程向数组添加新元素(并删除它们),另一个使用此数组(仅限读取操作).在我添加/删除数组或从中读取数组之前,是否有必要锁定数组?
更多详情:
我不认为这个问题"过于宽泛".如果仍然如此,请告诉我.我知道这个问题并不完美.为了能够解决问题,我必须至少结合3个答案 - 这表明大多数人无法完全理解所有问题,并被迫做一些猜测工作.但大多数都是通过我试图纳入问题的评论得出的.答案帮助我非常客观地解决了我的问题,我认为这里提供的答案对于从多线程开始的人来说是非常有用的资源.
弱指针就像智能指针,除了弱指针的引用不会阻止垃圾收集,弱指针必须在使用之前检查它们的有效性.
在我们的项目中(Linderdaum Engine http://www.linderdaum.com)中,我们使用了侵入式指针.为了避免循环引用和孤立孤岛,我们通过以下方式实现了弱入侵指针:
namespace LPtr
{
clPtr<iObject> GetObjectsGraphPtrWrapper( sEnvironment* Env, iObject* Obj, size_t Generation );
};
/// Intrusive weak smart pointer
template <class T> class clWeakPtr
{
public:
/// default constructor
clWeakPtr(): Env( NULL ), FObject( NULL ), FGeneration( 0 ) {}
explicit clWeakPtr( T* Ptr )
: Env( Ptr ? Ptr->Env : NULL )
, FObject( Ptr )
, FGeneration( Ptr ? Ptr->FGeneration : 0 ) {}
explicit clWeakPtr( const clPtr<T>& Ptr )
: Env( Ptr ? …Run Code Online (Sandbox Code Playgroud) 对高频交易/高性能计算感兴趣我遇到了“ACE”:
http://www.cs.wustl.edu/~schmidt/ACE-overview.html
但是,我注意到网站上的很多论文都是1995时代的,我想知道这个框架还在使用吗,如果没有,它是什么替代品?
或者有boost取代了这个?ACE 是否包含所需的增强功能的库?
我很难理解读者 - 写作者问题的第二种算法.我理解一般的概念,作家将优先于读者(读者可能会饿死).我甚至理解这个算法的读/写器锁在C++中的条件变量实现.但是,信号量和互斥量的实现对我来说毫无意义.这是维基百科的一个例子:
int readcount, writecount; (initial value = 0)
semaphore mutex 1, mutex 2, mutex 3, w, r ; (initial value = 1)
READER
P(mutex 3);
P(r);
P(mutex 1);
readcount := readcount + 1;
if readcount = 1 then P(w);
V(mutex 1);
V(r);
V(mutex 3);
reading is done
P(mutex 1);
readcount := readcount - 1;
if readcount = 0 then V(w);
V(mutex 1);
WRITER
P(mutex 2);
writecount := writecount + 1;
if writecount = 1 then P(r); …Run Code Online (Sandbox Code Playgroud) 让我们考虑一下C++中的这样一个类:
class CuteClass
{
public:
int getFancyInt() const;
float getNiceFloat() const;
string getPerfectString() const;
void setIntSomething(int something);
void setInternalState(State newState);
};
Run Code Online (Sandbox Code Playgroud)
可以从几个不同的线程同时访问此类的实例.然后:
所有getMethods(getFancyInt,getNiceFloat,getPerfectString)都不应该相互阻塞.它们不会更改对象的内部状态.
所有setMethod(setIntSomething,setInternalState)都应该:
带有互斥锁的简单lock_guard将满足除一个之外的所有要求 - getMethod将阻止其他getMethods.
在这种情况下,什么解决方案容易和干净?
我有一个对象列表Dinosaur,可以添加、删除这些对象,并且恐龙本身需要喂食。这一切都发生在高度多线程的环境中,因此列表受到互斥保护。
static Mutex s_dinosaurMutex;
static vector<Dinosaur> s_dinosaurList;
void AddDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
s_dinosaurList.push_back(dinosaur);
s_dinosaurMutex.Unlock();
}
void RemoveDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
if (it != s_dinosaurList.end())
s_dinosaurList.erase(it);
s_dinosaurMutex.Unlock();
}
void FeedDinosaur(const Dinosaur& dinosaur)
{
s_dinosaurMutex.Lock();
vector<IMadderReceiver*>::iterator it = find(s_dinosaurList.begin(), s_dinosaurList.end(), dinosaur);
if (it != s_dinosaurList.end())
(*it).Feed(); // Feeding a dinosaur can take a long time, ~ 1 second
s_dinosaurMutex.Unlock();
}
Run Code Online (Sandbox Code Playgroud)
现在问题出在喂养上。这可能需要很长时间,但如果多个线程同时喂养相同(或不同)的恐龙,那绝对没问题。因此,馈送过程不应停止其他FeedDinosaur调用,但应停止添加和删除调用,并等待这些调用完成。目前的行为是,许多线程正在排队以喂养恐龙,这使得系统陷入停滞。
是否有一种特定的(类似互斥体)设计模式允许需要只读访问的 ok-ing 线程的这种行为?
我有一个多线程C++应用程序,它在内存中保存一个复杂的数据结构(缓存数据).
我刚读完数据时一切都很棒.我可以拥有尽可能多的线程来访问数据.
但是,缓存的结构不是静态的.
"伪":
function getItem(key)
lockMutex()
foundItem = walkTreeToFindItem(key)
copyItem(foundItem, safeCopy)
unlockMutex()
return safeCopy
end function
function garbageCollection()
while item = nextItemInTree
if (tooOld) then
lockMutex()
deleteItem(item)
unlockMutex()
end if
end while
end function
Run Code Online (Sandbox Code Playgroud)
什么困扰我:这意味着,我在阅读时必须锁定树(以避免在我阅读时开始垃圾收集).然而 - 作为一种副作用 - 我也不能同时拥有两个阅读过程.
有什么建议?
是否存在某种"这只是一种只与写入冲突的只读动作"Mutex?
一个读取器线程和多个写入器线程同时访问shared_ptr对象并且它运行良好,代码如下(但是,如果我将写入行代码从“=”修改为“重置”,它将在读取时进行coredump):
shared_ptr.reset 意味着 coredump ,“operator =”意味着效果很好?(我试了100多次)
bool start = false;
std::mutex mtx;
std::condition_variable cond;
std::shared_ptr<std::string> string_ptr(new std::string("hello"));
int main() {
auto read = []() {
{
std::cout << "readddd" << std::endl;
std::unique_lock<std::mutex> lck(mtx);
while (!start) {
cond.wait(lck);
}
}
for (int i = 0; i < 100000; ++i) {
std::cout << *string_ptr.get() << std::endl;
}
};
auto write = []() {
{
std::unique_lock<std::mutex> lck(mtx);
while (!start) {
cond.wait(lck);
}
}
for (int i = 0; i < 100000; ++i) …Run Code Online (Sandbox Code Playgroud) c++ ×9
mutex ×4
boost ×3
ace ×2
c++11 ×2
concurrency ×2
algorithm ×1
arrays ×1
boost-thread ×1
c ×1
linux ×1
shared-ptr ×1
tcp ×1