Open gooker opened 1 year ago
已收到您的邮件,如有问题会尽快给您回复.
连接的时候使用如下的非阻塞方式,不确定对libgo 有没有影响
//非阻塞方式连接
int error=-1, len;
len = sizeof(int);
struct timeval tm;
fd_set set;
unsigned long ul = 1;
ioctl(sockfd, FIONBIO, &ul); //设置为非阻塞模式
if( connect(sockfd,(struct sockaddr *)&plcaddr,sizeof(plcaddr)) == -1)
{
tm={out_time,0};//10s
//tm.tv_set = TIME_OUT_TIME;
//tm.tv_uset = 0;
FD_ZERO(&set);
FD_SET(sockfd, &set);
if(select(sockfd+1, NULL, &set, NULL, &tm) > 0)
{
getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &error, (socklen_t *)&len);
if(error == 0)
ret = true;
else
ret = false;
}
else
ret = false;
}
else
ret = true;
ul = 0;
ioctl(sockfd, FIONBIO, &ul); //设置为阻塞模式
这库还维护不?我也遇到了死锁,服务跑几天就会出现,__lll_lock_wait只有一个线程出来,然后好几个线程在LFLock上面,把cpu都跑满了,提交的协程也不再执行,截几个图出来看有没帮助
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
@qinrhx 多谢,等有时间我试试,不好复现
我也遇到了这个问题,难受的一逼莫名奇妙死锁了。你用的是哪个版本
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
你换的哪个版本啊
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
@gooker 你用的哪个版本啊,跪求
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
@gooker 你用的哪个版本啊,跪求
我用的最新的,暂时没测试没换版本
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
@gooker 你用的哪个版本啊,跪求
我用的最新的,暂时没测试没换版本
@gooker matser分支不是还存在死锁问题嘛,我换3.1-stable发现这个版本有bug,携程有时候会空转
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
你换的哪个版本啊
@SignalEmit 具体哪个版本不记得了,是之前从master下载的,你找master提交记录更换锁套件之前的试试吧,比如这个
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
你换的哪个版本啊
@SignalEmit 具体哪个版本不记得了,是之前从master下载的,你找master提交记录更换锁套件之前的试试吧,比如这个 @qinrhx 我切过这个版本,这个版本有bug。举个例子 go[](){ while(true){ sleep(1); } }; 这个休眠挂起这里会出bug,无限空转,sleep也失效了。还会影响其他携程。3.1的稳定版也有这问题
@qinrhx 这个协程调用函数有锁,协程外也对这个锁也有处理,容易锁. 我这里只是用了tcp非阻塞遇到问题,改成阻塞貌似还正常.
我看更新记录,近期有更换了协程锁套件。应该是这个锁套件有bug,我换回原来的版本,跑了一个星期没出现死锁。 @gooker
你换的哪个版本啊
@SignalEmit 具体哪个版本不记得了,是之前从master下载的,你找master提交记录更换锁套件之前的试试吧,比如这个 @qinrhx 我切过这个版本,这个版本有bug。举个例子 go{ while(true){ sleep(1); } }; 这个休眠挂起这里会出bug,无限空转,sleep也失效了。还会影响其他携程。3.1的稳定版也有这问题
哦,这我倒没测过,我没有在协程里做循环休眠的。 之前是听说定时器有内存泄漏,失效的bug,你看看能不能改下业务逻辑避免掉了。 这个库看上去bug不少,也不怎么维护了,所以能不用就别用了。。。要用也简单用
@gooker @qinrhx
我这两天仔细看了一下这个代码,发现这个锁加的不太好,巨大的区域锁(有空了代码仔细看明白了,我重构重构这个锁)。上面那个tcp模块的死锁我找到原因了 复现方法:写了个httpserver epoll方式。开50个client并发,一直发发get请求,不出30秒就死锁了。
测试出了两处死锁
死锁1:
线程1
routine_sync/timer.h run函数 timer.h 150行 bool locked = invoke_lock.try_lock();
scheduler/processer.cpp WakeupBySelf函数 processer:cpp 381行 std::unique_lock
线程2
scheduler/processer.cpp WakeupBySelf函数 processer:cpp 381行 std::unique_lock
我仔细看了一下代码waitQueue_.LockRef()这个锁不好改,这个锁不仅锁携程调度队列,还要task,改了会导致压入的数据校验的时候,多线程会置空。我得做法是屏蔽掉 routine_sync/timer.h run函数 timer.h 128行 std::unique_lock
死锁2: 打开debug模式 DebugPrint宏里有个锁和TSQueue里的队列锁会形成死锁。
我得处理办法是 TSQueue size计数换成原子计数
@gooker @qinrhx
我这两天仔细看了一下这个代码,发现这个锁加的不太好,巨大的区域锁(有空了代码仔细看明白了,我重构重构这个锁)。上面那个tcp模块的死锁我找到原因了 复现方法:写了个httpserver epoll方式。开50个client并发,一直发发get请求,不出30秒就死锁了。
测试出了两处死锁
死锁1:
线程1
routine_sync/timer.h run函数 timer.h 150行 bool locked = invoke_lock.try_lock();
scheduler/processer.cpp WakeupBySelf函数 processer:cpp 381行 std::unique_lock
线程2
scheduler/processer.cpp WakeupBySelf函数 processer:cpp 381行 std::unique_lock
我仔细看了一下代码waitQueue_.LockRef()这个锁不好改,这个锁不仅锁携程调度队列,还要task,改了会导致压入的数据校验的时候,多线程会置空。我得做法是屏蔽掉 routine_sync/timer.h run函数 timer.h 128行 std::unique_lock
死锁2: 打开debug模式 DebugPrint宏里有个锁和TSQueue里的队列锁会形成死锁。
我得处理办法是 TSQueue size计数换成原子计数
现在这个库不怎么维护了是大问题,都不敢用了
centos7.8 gcc 10
场景很常见,目前一个设备,大约每秒1次执行下协程读取网口状态, 开始网络正常,然后断开设备网络,几个小时甚至更多就出现死锁,如下下数据 @yyzybb537 这个锁是libgo内部的吧
死锁情况