我在後端線程中使用libevent來運行hiredis並訂閱遠程redis數據庫。訂閱作品寄望用簡單的例子從另一個SO問題:如何通知運行libevent的線程應該採取一些措施?
然而,爲了避免競爭條件是不平凡的主線程添加訂閱。爲了達到這個目的,我創建了一個std::vector<std::string>
對象,其中包含後端應該訂閱的任何關鍵字符串。從這個向量讀/寫是通過一個互斥體執行的。
但是,如何通知後端添加了一些訂閱?目前我使用的定時器設置爲一個非常低的分辨率:
void Client::fireAndRequeueTimer(int fd, short e, void* arg)
{
Client* client = reinterpret_cast<Client*>(arg); // the client handles the subscription to redis (via hiredis/libevent)
if (client->mDisconnect)
return; // the main thread wants us to exit, so we don't recreate the timer
event* ev = &client->mTimerEvent; // some timer event object we created
timeval tv;
tv.tv_sec = 0;
tv.tv_usec = 1000; // 1ms
evtimer_add(ev, &tv);
// mPendingSubscriptions is an std::vector of strings, which contain the keys that we should add subscriptions to.
if (client->mPendingSubscriptions.size())
{
std::unique_lock<std::mutex> lock(client->mSubscriptionsMutex);
do
{
redisAsyncCommand(
client->mContext,
Client::subCallback,
(char*)"sub",
"SUBSCRIBE %s",
client->mPendingSubscriptions.back().c_str());
client->mPendingSubscriptions.pop_back();
}
while (client->mPendingSubscriptions.size());
}
}
(請注意,我用libevent 1.4.x
這樣的功能,如EV_PERSIST不存在的,我必須重新在每個事件定時器)。
雖然上述作品,我很不滿意的話,原因如下:
- 它放置在後端不必要的壓力不斷輪詢載體。
- 讀者很難沒有廣泛的評論
- 它很慢;這個定時器會爲訂閱一個事件增加多達1ms的時間。這可能很重要,也可能不會,但無論如何,這是浪費時間。
是否有這個問題,將的libevent 1.4.x
範圍內解決這些問題的任何溶液?
不確定libevent是否使用pthreads?如果是這樣,你可以使用一個信號,例如SIGHUP,並設置pthread的sigmask,所以只有你的後端線程會接受信號? –