在pthread中调用done->Run()是否会存在潜在的bthread调用?
在异步的服务端代码中,我们把请求入口处的done对象保存了下来。再之后某个时间,请求处理完成后,再调用done->Run()。
显然,在请求入口的时候,代码是在bthread中运行的。但是假如我们在异步服务的实现中,保证调用done->Run()的环境一定不是bthread,那么该调用是否会有潜在的调用会在bthread中运行呢?更具体来说,是HttpResponseSenderAsDone::Run()的调用。
更具体来说,现在我们的代码会在pthread中(一个和brpc无关的独立线程池)调用done->Run(),但是调用的时候获取到了一个互斥锁,且该互斥锁不是butex。而该服务所有的rpc请求在刚刚开始处理的时候也会尝试获取相同的互斥锁(这时候代码是在bthread中运行的)。如果即使是pthread中调用done->Run()也可能请求到bthread。那么我们现在这样的逻辑会有死锁风险。详情如下:
- pthread获取到了mutex,然后即将调用done->Run()。
- 有大量新请求到达,所有的bthread worker都去处理这些新的请求了,然后因为在bthread中尝试获取mutex,导致所有的bthread worker被阻塞。
- pthread开始调用done->Run(),在这过程中又去请求bthread,因为bthread worker全被阻塞了,于是触发死锁。 但如果pthread中调用done->Run()不会请求bthread,则死锁不会发生,以上逻辑是安全的。
请帮我核实在pthread中调用done->Run()是否会请求到bthread呢?或者说,brpc在发送回复时,是否有逻辑一定会在bthread上运行,即使done->Run()是在pthread里调用的?
假定这里的设置都是默认的,done->Run()会让回调运行在独立的bthread中,done->Run()里只是创建。所以如果bthread不是特别多,且pthread在调用done->Run()时全程带锁,这里也不会死锁。但有一些设置可以让Done原地运行,这个要检查一下
假定这里的设置都是默认的,done->Run()会让回调运行在独立的bthread中,done->Run()里只是创建。所以如果bthread不是特别多,且pthread在调用done->Run()时全程带锁,这里也不会死锁。但有一些设置可以让Done原地运行,这个要检查一下
请问一下是什么设置呢。
另外“done->Run()会让回调运行在独立的bthread中,done->Run()里只是创建”的意思是否是指done->Run()创建了新的bthread后直接返回,而不会join它。在这种情况下,即使新的bthread中去请求了mutex也不会死锁。因为pthread在done->Run()时不会被阻塞,可以之后把mutex释放,从而让bthread worker可以继续工作。
我理解在这个情况下确实不会死锁,但是如果done->Run()要等待这个bthread里的回调执行完,那还是会死锁的。
应该是FLAGS_usercode_in_pthread这个gflag设置吧。
done->Run()不会等。