Anonymous
а мне нужно сортировать по времени создания
Alexander
нужно указать свой компаратор или взять другой контейнер
Anonymous
компаратор указал, контейнер низя другой
Alexander
std::map<uint256, XBridgeTransactionDescrPtr, MyCompare>
Alexander
третим аргументом задаётся свой компаратор
Anonymous
auto cmp = [timestamp](const TransactionPair &a, const TransactionPair &b)
{
return timestamp(a.second->created) < timestamp(b.second->created);
};
std::sort(trList.begin(), trList.end(), cmp);
Berkus
но это не лист
Berkus
у мапы нельзя брать разность итераторов
Viacheslav
std::sort неприменим для std::map.
Berkus
т.к. не существует distance(it1, it2) в мапе
Viacheslav
Berkus
Anonymous
все, спасбо, перемудрил
Александр
Товарищи, а никто не пользовался srcML? http://www.srcml.org
Roman
Существуют ли серьёзные имплементации "green thread'ов" на C++? грубо говоря что-то на подобии Golang Goroutines?
Roman
После написания вебсервера на Go писать аналогичный софт на C++ просто жутко. Non-blocking concurrent code намного сложнее писать на традиционных потоках нежели на goroutine'ах, которые можно спокойно блокировать
писать в асинхронном стиле с использованием Event Loop'а тоже не особо
Viacheslav
boost::asio, coroutines.
Roman
нашёл лишь https://github.com/nifigase/greeny
но на серьёзное решение не похоже
Roman
Эээ, сервер например? Это самая многопоточная среда
Viacheslav
Нахрена для сервера именно зелёные потоки?
Viacheslav
Для того, чтобы писать в синхронном стиле, в стандарт как раз тащат coroutines.
Viacheslav
Кроме того, зелёные потоки без GC работают через задницу.
Viacheslav
Rust пытался их протащить в начале своего развития, потом выбросили всю концепцию напрочь.
Roman
Нахрена для сервера именно зелёные потоки?
потому-что это не усложняет код. Потоки обрабатывающие запросы имеют свойство блокироваться, например при работе с БД, FS и подобным IO. Блокировать основные потоки очень нехорошо, а green потоки блокировать не страшно
Viacheslav
У тебя твои green потоки будут всё так же через какой-то scheduler работать.
Viacheslav
boost::asio предоставляет как раз его, и coroutines уже поддерживает.
Viacheslav
Так что при желании можно писать уже сейчас.
Roman
Viacheslav
можно ссылочку пож?
Не могу, тут администраторы что=то намудрили и ссылки не вставляются.
Egor
Viacheslav
Зелёные они потому, что стэк маленький.
Egor
Особенно непонятно, чем в этом месте корутины отличаются от обычных потоков, с которыми вполне можно работать без GC
Egor
Viacheslav
И. Если ему надо расти, удачи в перемещении объектов.
Viacheslav
Copying or segmented stacks. In Go, there is no need to provide a maximum stack size for the goroutine. The stack grows incrementally as needed. One consequence is a goroutine does not require much memory (4KB-8KB), so a huge number of them can be happily spawned. Goroutine usage can therefore be pervasive.
В Go так.
Viacheslav
[rust-dev] Abandoning segmented stacks in Rust — искать по этим ключевым словам, почему не пошло.
Viacheslav
Ну реализуй мне green threads without stacks. Не stackless coroutines, а именно зелёные потоки с userspace scheduling.
Roman
С того перепугу когда увидишь и сравнишь код на C++ и Go))
на Go реально намного проще и чище конкуррентный, асинхронный, неблокирующий код.
Viacheslav
Roman
я же тебе написал. Они нужны тогда, когда у тебя много конкуррентных/параллельных процессов, и тебе нельзя блокировать системные потоки работой с IO, и когда event loop - не вариант
Viacheslav
И почему event loop не вариант?
Viacheslav
Если аргумент в том, что получается лапша из callbacks, то над этим работают.
Roman
И почему event loop не вариант?
по нескольким причинам, спонтанно могу назвать:
- потому-что это 1 поток логики, и чтоб его слишком не нагружать - часть кода нужно реализовывать отдельными thread pool'ами, что сложнее и код становится менее однородным
- потому-что программировать придётся в асинхронном стиле (аля JavaScript), не синхронном как на Go
Viacheslav
И errno не использует никогда?
Viacheslav
Это thread-local объект, внезапно.
Viacheslav
Roman
мы не можем использовать стандартные системные потоки. Ибо иначе мы либо будем их блокировать что вообще не гут, либо создавать их тоннами, что ещё более не гут
Roman
ну так правильно, я же перечислил benefit'ы, почему я так привык думать после Go
просто тупо легче, на написание non-block async concr. кода уходит куда меньше времени и усилий
Roman
OS thread
Viacheslav
Roman
для меня самый идеальный вариант для решения данной проблемы на данный момент это Go
просто Go это как-бы Google, и как-бы GC, и как-бы довольно специфический язык (язык конечно не плох, но отсутствие generic'ов всё-таки сказывается) и хотелось бы видеть что-то подобноее для C++
Roman
user-space scheduling, non-blocking asynchronous code in a synchronous manner
Roman
event loop'ов мне из JavaScript Node.js и Qt хватило
ttldtor
ок, и ты ничего не нашёл?
Viacheslav
Thanks to co_await, the blocking calls can now be suspended and resumed.
Acceptor acceptor{443};
while (true){
Socket socket= co_await acceptor.accept();
auto request= co_await socket.read();
auto response= handleRequest(request);
co_await socket.write(responste);
}
Max
влезу со своим !техническим мнением в дискуссию, и поддержу Илью - спор о субьективных вещах
Viacheslav
Viacheslav
Не вижу, куда ещё синхроннее.
Roman
Viacheslav
ttldtor
корутины, файберы...
Roman
Roman
с WinAPI не работал, не знаю
ttldtor
Roman
надо лучше изучить тематику
ttldtor
Если ивентлуп - это проблема, то проблема надуманная
Roman
"почти" это как понять? какова разница?
ttldtor
но ведь под капотом у го ивентлуп)
Roman
Go после Node и Qt это чудо))
Roman
Go:
func doBlockingStuff() error {
fileContents, err := file.read() // blocking
if err != nil {
// file read failed
err = database.write(emergencyData) // blocking
if err != nil {
// emergency database write failed
return err
}
return err
}
err = database.write(fileContents) // blocking
if err != nil {
// database write failed
return err
}
return nil
}
JS (Promises)
function doBlockingStuff() {
return new Promise((resolve, reject) => {
file.read()
.then(fileContents => {
return database.write(fileContents)
})
.then(() => {
resolve()
})
.catch(err => {
switch err.name {
case FileReadFailed:
database.write(emergencyData)
.then(() => { resolve() })
.catch(err => { reject(err) })
break
default:
reject(err)
}
})
})
}
ttldtor
кхм, мне кажется, что противопоставлять асинхронное и синхронное, это как противопоставлять иммутабельное и мутабельное... демагогия
Roman
Roman
и это я ещё не писал на callback'ах (ибо лютый ад получится)