admin管理员组文章数量:1599535
声明了一个类,内部通过std::unique_ptr使用了muduo::net::TcpClient
class SendData
{
public:
SendData();
~SendData() = default;
private:
void onConnection(const muduo::net::TcpConnectionPtr& conn)
{
// do something
m_cv.notify_one()
}
private:
std::unique_ptr<muduo::net::TcpClient> m_pTcpClient;
std::condition_variable m_cv
};
在程序内部创建了TcpClient,并连接了服务端。
连接断开的方法,采用了释放TcpClient对象的方式。
当TcpClient对象释放时会进行连接断开,此时会将连接结果通过回调函数反馈回来。
EventLoop反馈断开结果时,可能对象已经释放或者说condition_variable对象已经释放了。
回调函数还用的原来的地址执行了回调函数,此时执行到m_cv.notify_one可能会导致卡住
(linux_3.10 中通过gdb找到卡住的线程,通过调用堆栈是condition_variable中的__lll_lock_wait锁住)。
#0 0x00007ffff78c554d in __lll_lock_wait () from /lib64/libpthread.so.0
#1 0x00007ffff78c314d in pthread_cond_signal@@GLIBC_2.3.2 () from /lib64/libpthread.so.0
#2 0x00007ffff7b84b09 in std::condition_variable::notify_one() () from /lib64/libstdc++.so.6
=================================
通过写测试程序进行模拟,也没有模拟出来。如果有好的模拟方法,请指导。
#include <stdlib.h>
#include <stdio.h>
#include <condition_variable>
#include <thread>
int main()
{
std::condition_variable *pcv;
{
std::condition_variable cv;
pcv = &cv;
for(int i = 0; i < 10; i++)
{
cv.notify_one();
fprintf(stderr, "notify %d times.\n", i + 1);
}
cv.notify_all();
}
std::this_thread::sleep_for(std::chrono::seconds(1));
pcv->notify_one();
fprintf(stderr, "use dtor cv to notify_one.\n");
return 0;
}
=================================
通过设置标志位来避免上述死锁的方式。当开始析构时设置标记位,回调函数发现了标志位,就直接退出。
本文标签: 死锁情况conditionvariable
版权声明:本文标题:【死锁】condition_variable导致一种死锁情况 内容由热心网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:https://m.elefans.com/dianzi/1728322644a1154028.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论