- 主题:经典死锁
除了这种交叉加锁,
void Foo()
{
std::lock_guard guard1{m_mutex1};
std::lock_guard guard2{m_mutex2};
...
}
void Bar()
{
std::lock_guard guard2{m_mutex2};
std::lock_guard guard1{m_mutex1};
...
}
看到好多这种死锁:
int ThreadProc() {
...
std::lock_guard guard{m_mutex};
...
}
void StopThread()
{
std::lock_guard guard{m_mutex};
if (m_thread != nullptr)
{
m_thread->join();
delete m_thread;
m_thread = nullptr;
}
}
--
FROM 114.241.228.*
你的意思是这么用的不是人吗?哈哈
【 在 ylh1969 的大作中提到: 】
: 没人这么用吧!
--
FROM 114.241.228.*
那只能说明您老用得少
1、std::scoped_lock就是用来解决交叉加锁的,先try_lock试探一下。当然,不加双锁最好了
2、拿着锁去join那些可能会请求锁的线程的,我看到不止3起了。
【 在 ylh1969 的大作中提到: 】
: 有成功的吗?
--
FROM 114.241.228.*
.dll/.so里不能有野线程。试想一下dll被unload后,那个野线程还在跑的话。
【 在 ylh1969 的大作中提到: 】
: }
: //设置分离线程
: ret=pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED);
: ...................
--
FROM 114.241.228.*
的确是可以弄把小锁,专门锁这个线程句柄。线程自己不要操作自己的句柄,也就不会去请求这个小锁
【 在 JetLan 的大作中提到: 】
: 设计的问题,锁的颗粒度太大了。
:
--
FROM 114.241.228.*
场景是dll中按需启、停某些单例的功能,这些单例中有开线程。
【 在 brucewww 的大作中提到: 】
: 我觉得也是,很多设计上可以避免持锁操作。
:
--
FROM 114.241.228.*
在类中开线程,可以给线程lambda传递this指针,比较方便访问类的private member
解决办法是有的,除了上面说的用小锁,
另一个办法是拿着锁,move到临时变量里,放掉锁,再join线程
【 在 ylh1969 的大作中提到: 】
: 不要在单例中调用线程,而是在线程中调用单例。
--
修改:z16166 FROM 114.241.228.*
FROM 114.241.228.*
您那个动态加载没啥问题,是常见手法,要看锁的粒度是到dll/so,还是到dll/so导出的每个接口。
有个userspace RCU,借鉴的linux kernel的搞法,专门解决read-copy-update场景的需求,貌似也可以用来更新这个dll/so导出的接口指针表。
【 在 ylh1969 的大作中提到: 】
: 你愿意怎么办就怎么办吧。
: 反正,我给你看了那个动态模块热插拔管理。
: 不需要模块内部关心什么线程协程。
: ...................
--
FROM 114.241.228.*