using Ta = some copyable UDT;
using Tb = another copyable UDT;
class A {
public:
map<int, Ta> m;
mutex mut;
Ta find(int i) {
lock_guard<mutex> lk(mut);
if (auto it = m.find(i); it != m.end()) {
return it->second;
}
}
void update(int i, const Ta& data) {
lock_guard<mutex> lk(mut);
m[i] = data;
}
};
class B {
public:
map<int, Tb> m;
mutex mut;
Tb find(int i) {
lock_guard<mutex> lk(mut);
if (auto it = m.find(i); it != m.end()) {
return it->second;
}
}
void update(int i, const Tb& data) {
lock_guard<mutex> lk(mut);
m[i] = data;
}
};
If codes are like above, and to make it simple, I make all variables public, and A::m
and B::m
have some relationship, If some data inserts into A::m
, it should also insert into B::m
, delete as well(i.e. datas should both be valid in A::m
and B::m
)
Now I want to find some data in A
and update it into B
A a;
B b;
some init...
auto data = a.find(1);
b.update(1, process(data));
But I wonder, if some thread just delete the data after a.find(1)
, and it makes the data actually invalid, and it makes b.update(1, process(data));
actually meanningless too.
But if I write like
lock_guard<mutex> lk(A::mut);
if (auto it = A::m.find(i); it != A::m.end()) {
auto& data = it->second;
{
lock_guard<mutex> lk(B::mut);
B::m[i] = data;
}
}
It makes A::mut and B::mut nested, and I think it could cause deadlock. So do my two concerns make sense? And is there any perfect solution to use a thread-safe data into another thread-safe data?