我正在尝试基于 libtorrent rasterbar 编写自己的 torrent 程序,但在让警报机制正常工作时遇到问题。Libtorrent 提供功能
void set_alert_notify (boost::function<void()> const& fun);
这应该是
该函数的目的是客户端唤醒其主线程,以使用 pop_alerts() 轮询更多警报。如果 notify 函数没有这样做,它将不会被再次调用,直到 pop_alerts 因其他原因被调用。
到目前为止一切顺利,我想我理解了这个功能背后的意图。但是,我的实际实现并没有那么好。到目前为止,我的代码是这样的:
std::unique_lock<std::mutex> ul(_alert_m);
session.set_alert_notify([&]() { _alert_cv.notify_one(); });
while (!_alert_loop_should_stop) {
if (!session.wait_for_alert(std::chrono::seconds(0))) {
_alert_cv.wait(ul);
}
std::vector<libtorrent::alert*> alerts;
session.pop_alerts(&alerts);
for (auto alert : alerts) {
LTi_ << alert->message();
}
}
但是有一个竞争条件。如果wait_for_alert
返回NULL
(因为还没有警报)但传递给的函数set_alert_notify
在之前被调用_alert_cw.wait(ul);
,则整个循环将永远等待(因为引用中的第二句)。
目前,我的解决方案只是改变_alert_cv.wait(ul);
为_alert_cv.wait_for(ul, std::chrono::milliseconds(250));
在保持足够低的延迟的同时减少每秒的循环数。
但这确实是比解决方案更多的解决方法,我一直认为必须有适当的方法来处理这个问题。