[C++] А как сейчас модно сетевые сервера писать?
void watcher_callback(struct ev_loop *loop, ev_io *w, int tev)
{
/* do recv(2) */
ev_io_stop(loop, w);
}
...
ev_io_init(watcher, watcher_callback, sd, EV_READ);
ev_io_start(loop, watcher);
...
ev_run(loop, 0);
но это наверное слишком вручную для тебя будет.
хотя тут тоже по сути дела только задаешь коллбек и все.
но правда надо еще открыть сокет и сказать ему FIONBIO, но это вроде просто...
sd = socket(AF_..., SOCK_..., ...);
int nbio_value = 1;
ioctl(sd, FIONBIO, &nbio_value);
зато ничего "под нагрузкой периодически внезапно" не "подвисает где-то на минуту".
короче, вряд ли тебе мой совет помог.
короче, вряд ли тебе мой совет помог.Увы По докам, конечно, всё круто и ваще, но как посмотрю на все эти "Кстати, память под ваши watcher'ы надо выделять самому, ручками, ах да, выделять её на стэке — это обычно плохая идея", сразу так тоскливо становится.
Мне очень нравится, как можно сделать в ømq:
zmq::context_t context(0);
zmq::socket_t clients(context, ZMQ_XREP);
clients.bind("tcp://*:12345");
zmq::socket_t workers(context, ZMQ_XREQ);
workers.bind("inproc://workers");
std::thread* t[workerCount];
for (unsigned int i = 0; i < workerCount; ++i)
t[i] = new std::thread(worker_routine, &context);
zmq::device(ZMQ_QUEUE, clients, workers);
...
void worker_routine (zmq::context_t *context)
{
zmq::socket_t socket(*context, ZMQ_REP);
socket.connect("inproc://workers");
while(true)
{
zmq::message_t request;
socket.recv(&request);
/* do some work */
socket.send(reply);
}
}
Но у него, помимо вышеупомянутого косяка (я всё ещё лелею надежду, что может это мой баг есть ещё одна проблема: у него свой формат передачи данных, поэтому клиент должен быть написан на нём же.
Зато у Бачана код короче )
В треде ещё пианиста нехватает. Подождём ...
Зато у Бачана код короче )у пианиста, надо полагать, код толще будет
Попробовал было ØMQ, всем прекрасен, только под нагрузкой периодически внезапно подвисает где-то на минуту, потом раздупляется — пытался грешить на свой код, но не смог: кода всего пара страниц, система многопроцессорная, никаких блокировок, все классы, кроме ØMQ, стандартные STL-ные.какая версия ØMQ?
в список рассылки не писал? почему?
2.1.7. Не писал, потому что до конца не уверен, что проблема с их стороны. Я лучше сначала локализую проблему, потом буду уже им писать.
В треде ещё пианиста нехватает. Подождём ...Про сетевые вещи я знаю только одно: надо спросить Бачана, он скажет как делать.
Бачан отписался, мне добавить нечего.
Могу только ещё как совет добавить: не использовать треш-библиотеки.
После фикса уже полтора часа работает стабильно, если сутки ещё отпашет нормально, можно будет с уверенностью говорить, что ømq — это круто.
Кстати, судя по всему, косяк действительно был у меня: я заюзал std::unordered_map из c++0x, и в какие-то моменты он начинал увеличивать свой размер и рехэшировать данные, что и приводило к таким тормозам, так что дурак действительно я.ничего себе у тебя хеш-мапчик! данные минуту перекладывает!
сколько ж у тебя там данных-то?
и как пофиксил?
и откуда STL? g++-ный?
Кстати, память под ваши watcher'ы надо выделять самому, ручками, ах да, выделять её на стэке — это обычно плохая идеяа я помню что-то такое из доки, но как-то смутно... и, короче, не парюсь и выделяю на стеке. там в рассылке у леманна обсуждалось, что могут быть проблемы с отступами на каких-то неведомых архитектурах, но это архитектуры какие-то совсем неведомые (для меня так что пока все окейно было... =)
ничего себе у тебя хеш-мапчик! данные минуту перекладывает!С гиг где-то.
сколько ж у тебя там данных-то?
и как пофиксил?
и откуда STL? g++-ный?
Взял да и заменил на обычный map. Скорость выборки возрастает некритично, зато перестраивать при увеличении не нужно.
g++-ный, да. На машине только 4.4 есть, так что очень теоретически это ещё может быть причиной — я люблю использовать всякое из c++0x, а в 4.4 поддержка ещё не слишком хороша.
и он не перестраивался почему-то, правда он обычно на старте заполнялся чем-то сохраненным.
ну ладно, понятно. спасибо!
гига по 2-4. может и 8 было где-то...Видимо вы действительно могли заранее предсказать размер и выделить память.
и он не перестраивался почему-то, правда он обычно на старте заполнялся чем-то сохраненным.
http://google-sparsehash.googlecode.com/svn/trunk/doc/sparse...
[6] sparse_hash_map requires you call set_deleted_key before calling erase. (This is the largest difference between the sparse_hash_map API and other hash-map APIs. See implementation.html for why this is necessary.) The argument to set_deleted_key should be a key-value that is never used for legitimate hash-map entries. It is an error to call erase without first calling set_deleted_key and it is also an error to call insert with an item whose key is the "deleted key."пипец, блин. очень неудобно, зачем вообще такие алгоритмы использовать, которые требуют deleted_key?
и потом, если уж пишешь drop-in replacement для std::map, то путь он будет до конца drop-in.
а не с вот такой вот заковыкой 6-ым пунктом в примечаниях мелким текстом.
причем, ладно бы он был каким-нибудь суперэффективным (хотя он неплох).
но он проигрывает judy и по скорости, и по размеру на всех задачах (+попсовых железках к ним что я видел.
а judy не нужно никакого deleted_key и прочей лабуды.
Оставить комментарий
doublemother
Я имею в виду, чем принято пользоваться и всё такое. Развлекаться с сырой сишной работой со всеми этими bind accept poll и т.п. не хочется. Использовать что-то монструозное типа QTcpServer — тоже.Попробовал было ØMQ, всем прекрасен, только под нагрузкой периодически внезапно подвисает где-то на минуту, потом раздупляется — пытался грешить на свой код, но не смог: кода всего пара страниц, система многопроцессорная, никаких блокировок, все классы, кроме ØMQ, стандартные STL-ные.
Хочется что-то простое, хорошо параллелящееся, чтобы, грубо говоря, в идеале я мог задать обработчики и не париться с приёмом запроса, отсылкой ответа, созданием нового воркера или передачей запроса уже имеющемуся.
Upd. Да, интересуют только линуксы.