我正在尝试编写基于libtorrent rasterbar的自己的torrent程序,并且我在使警报机制正常工作时遇到问题。 Libtorrent提供功能
self::$rCh = curl_init();
curl_setopt( self::$rCh, CURLOPT_RETURNTRANSFER, true );
curl_setopt( self::$rCh, CURLOPT_TIMEOUT, 30 );
curl_setopt( self::$rCh, CURLOPT_CONNECTTIMEOUT, self::iTimeout );
curl_setopt( self::$rCh, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows; U;
Windows NT 5.1; en-US; rv:1.8.1.13) Gecko/20080311 Firefox/2.0.0.13' );
curl_setopt( self::$rCh, CURLOPT_SSL_VERIFYHOST, 0 );
curl_setopt( self::$rCh, CURLOPT_SSL_VERIFYPEER, 0 );
curl_setopt( self::$rCh, CURLOPT_POST, 0 );
curl_setopt( self::$rCh, CURLOPT_PROXY, 'a123:b123:123::1' );
curl_setopt( self::$rCh, CURLOPT_PROXYPORT, 12345 );
$sPage = curl_exec( self::$rCh );
应该是
到目前为止这么好,我想我理解这个功能背后的意图。但是,我的实际实现效果不是很好。到目前为止我的代码是这样的:该函数的目的是客户端唤醒其主线程,使用pop_alerts()轮询更多警报。如果notify函数无法执行此操作,则在调用pop_alerts之前不会再次调用它。
void set_alert_notify (boost::function<void()> const& fun);
然而,有一个竞争条件。如果 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);
,这足以减少每秒的循环次数,同时保持足够低的延迟。
但实际上解决方案确实更具解决方法,我一直认为必须有适当的方法来解决这个问题。
答案 0 :(得分:0)
您需要一个变量来记录通知。它应该由拥有条件变量的相同互斥锁保护。
bool _alert_pending;
session.set_alert_notify([&]() {
std::lock_guard<std::mutex> lg(_alert_m);
_alert_pending = true;
_alert_cv.notify_one();
});
std::unique_lock<std::mutex> ul(_alert_m);
while(!_alert_loop_should_stop) {
_alert_cv.wait(ul, [&]() {
return _alert_pending || _alert_loop_should_stop;
})
if(_alert_pending) {
_alert_pending = false;
ul.unlock();
session.pop_alerts(...);
...
ul.lock();
}
}