Надо немножко многопоточности добавить в прогу, решил использовать стандартное плюсовое, которое недавно завезли. Раньше работал в основном с виндовыми потоками и объектами синхронизации, но немного и POSIX трогал.
Появились вопросы. В винде я обычно использовал CriticalSection — она позволяет уже залочившему потоку многократно делать лок без блокирования. Думал, std::mutex — это то, что мне нужно, но нет: If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock. А я не хочу парится об этом, и помнить, какая функция у меня лочит, а какая — нет.
Далее. В винде есть Events или как-то так, могут быть в сигнальном и несигнальном состоянии. Вроде бы std::binary_semaphore похож на то, что мне нужно, но не уверен. Как получить на нем семантику SetEvent/ResetEvent/WaitFor?
Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы
ЗЗЫ Может, часть из того что нужно можно на атомиках сделать? Или это плохая идея?
Что знаю, скажу, остальное не делал.
П>Появились вопросы. В винде я обычно использовал CriticalSection — она позволяет уже залочившему потоку многократно делать лок без блокирования. Думал, std::mutex — это то, что мне нужно, но нет: If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock. А я не хочу парится об этом, и помнить, какая функция у меня лочит, а какая — нет.
Если какая функция лочит и потом анлочит, то recursive_mutex вроде то что надо.
Сколько локов — столько и анлоков.
П>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
Здравствуйте, пффф, Вы писали:
П>Привет!
П>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы Почитайте на досуге
Здравствуйте, Dair, Вы писали:
D>Если какая функция лочит и потом анлочит, то recursive_mutex вроде то что надо. D>Сколько локов — столько и анлоков.
Да, точно, оно самое. Только вопрос такой — CriticalSection вроде как легковесный, спин лок, а мьютекс — это обычно сразу ядрёный вызов. В принципе, сейчас-то наплевать, но в целях саморазвития, есть что-то подобное лёгкое?
П>>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
D>Лямбда, например?
D>
Здравствуйте, kov_serg, Вы писали:
П>>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы _>Почитайте на досуге
О, спасибо, на досуге почитаю. А сейчас код колбасить надо, может подскажешь по-быстрому?
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, Dair, Вы писали:
D>>Если какая функция лочит и потом анлочит, то recursive_mutex вроде то что надо. D>>Сколько локов — столько и анлоков.
П>Да, точно, оно самое. Только вопрос такой — CriticalSection вроде как легковесный, спин лок, а мьютекс — это обычно сразу ядрёный вызов. В принципе, сейчас-то наплевать, но в целях саморазвития, есть что-то подобное лёгкое?
Мне надо сделать поток и два сигнала. Один сигнал — что для потока есть работа, воркер на нем спит, основной поток сигналит, воркер просыпается, сбрасывает сигнал, делает работу, и опять засыпает, или, если второй стоп-сигнал тоже активен — завершает работу. Второй сигнал — что воркеру надо завершиться — ставим его в сигнальное состояние, затем будим поток по первому сигналу, и ждём завершения.
1) Нормальная ли логика, или я что-то пропустил?
2) Не очень понятно, как это все инициализировать, при условии, что это всё члены одного класса, и поток будет выполнять один из методов этого класса. Как это всё правильно сделать?
Здравствуйте, vopl, Вы писали:
П>>Наверное да, но тогда имхо и std::function должен проканать, а он вроде умеет в методы экземпляра объекта. Но я просто никогда этим не пользовался
V>на метод можно выйти так V>
Мне бы всё в конструкторе разрулить. Как я понял, std::thread'у надо указать функцию, которую он сразу начнёт выполнять. И нет никакого неактивного состояния, чтобы чтобы задать функцию потока, но отложить выполнение до вызова .run(), и нет возможности создать объект потока без функции, и потом запустить — .run(func)
Здравствуйте, ArtDenis, Вы писали:
П>>О, спасибо, на досуге почитаю. А сейчас код колбасить надо, может подскажешь по-быстрому?
AD>Если по-быстрому, то лучше писать так как привык (дёргая низкоуровневые API)
Не хочу, хочу переносимо, а писать две реализации для WinAPI и POSIX — уже старый стал, ленивый
Правильно ли я понимаю, что std::lock_guard и std::scoped_lock — аналогичны, но второй может лочить пачки разнородных объектов, а первый — только один mutex_type мьютекс?
Здравствуйте, vopl, Вы писали:
D>>>Если какая функция лочит и потом анлочит, то recursive_mutex вроде то что надо. D>>>Сколько локов — столько и анлоков.
П>>Да, точно, оно самое. Только вопрос такой — CriticalSection вроде как легковесный, спин лок, а мьютекс — это обычно сразу ядрёный вызов. В принципе, сейчас-то наплевать, но в целях саморазвития, есть что-то подобное лёгкое?
V>std::mutex и winapi-mutex это существенно разные вещи, не нужно из путать. std::mutex обычно реализован через winapi-CriticalSection, в живую все это увидеть можно примерно тут
Могли бы отдельно спин-лок класс сделать, а не путать народ. В винде мьютекс можно шарить между процессами, а в плюсиках как с этим? Или такого нет?
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, пффф, Вы писали:
П>Да, и ещё.
П>Мне надо сделать поток и два сигнала. Один сигнал — что для потока есть работа, воркер на нем спит, основной поток сигналит, воркер просыпается, сбрасывает сигнал, делает работу, и опять засыпает, или, если второй стоп-сигнал тоже активен — завершает работу. Второй сигнал — что воркеру надо завершиться — ставим его в сигнальное состояние, затем будим поток по первому сигналу, и ждём завершения.
я понимаю что это не по фуншую но работает под win and linux
Здравствуйте, kov_serg, Вы писали:
П>>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы _>Почитайте на досуге
Полистал. Похоже, что если по такой книжке учиться, то хорошего кода не получится.
Здравствуйте, B0FEE664, Вы писали:
BFE>Полистал. Похоже, что если по такой книжке учиться, то хорошего кода не получится.
Так этож новое молодёжное. Если хочется хорошего есть https://github.com/taskflow/taskflow
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, vopl, Вы писали:
П>>>Наверное да, но тогда имхо и std::function должен проканать, а он вроде умеет в методы экземпляра объекта. Но я просто никогда этим не пользовался
V>>на метод можно выйти так V>>
П>Мне бы всё в конструкторе разрулить. Как я понял, std::thread'у надо указать функцию, которую он сразу начнёт выполнять. И нет никакого неактивного состояния, чтобы чтобы задать функцию потока, но отложить выполнение до вызова .run(), и нет возможности создать объект потока без функции, и потом запустить — .run(func)
Если я правильно понял..
class MyClass
{
public:
MyClass()
{
}
void run()
{
worker = std::thred{[this]{
//и вызывай любые методы в этом потоке
}};
}
~MyClass()
{
if(worker.joinable()) worker.join();
}
private:
std::thread worker;
}
MyClass myObj;// теперь там внутри как бы есть работающий поток
А вообще, лучше такое не на форуме спрашивать а самому вот тут смотреть https://en.cppreference.com/w/cpp/thread/thread, там номенклатура методов представлена, сразу видно что поток может и чего не может.
Здравствуйте, пффф, Вы писали:
V>>std::mutex и winapi-mutex это существенно разные вещи, не нужно из путать. std::mutex обычно реализован через winapi-CriticalSection, в живую все это увидеть можно примерно тут
П>Могли бы отдельно спин-лок класс сделать, а не путать народ.
Да вроде никто и не путается, ты первый жалуешся
П>В винде мьютекс можно шарить между процессами, а в плюсиках как с этим? Или такого нет?
Нет.
Здравствуйте, vopl, Вы писали:
V>А вообще, лучше такое не на форуме спрашивать а самому вот тут смотреть https://en.cppreference.com/w/cpp/thread/thread, там номенклатура методов представлена, сразу видно что поток может и чего не может.
Да я смотрел, не совсем всё понятно.
Пораскинул, получается так: если мы хотим сделать изначально спящий поток, то просто конструируем без адреса функции: auto th = std::thread() (но на самом деле никакого потока не будет создано), если хотим сделать run(func), делаем th = std::thread(func), а вот чтобы при создании задать функцию потока, но отложить его запуск до лучших времён — такого нет
Здравствуйте, пффф, Вы писали:
П>CriticalSection вроде как легковесный, спин лок
Не, он сначала "спинает в гробу" а если спинал слишком долго тогда взыхает и переходит к более тяжёлому ожиданию.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
П>>CriticalSection вроде как легковесный, спин лок CC>Не, он сначала "спинает в гробу" а если спинал слишком долго тогда взыхает и переходит к более тяжёлому ожиданию.
Да, спасибо, я в курсе, как и о том, что начиная с XP спин каунтер можно задавать
Здравствуйте, пффф, Вы писали:
П>Мне надо сделать поток и два сигнала. Один сигнал — что для потока есть работа, воркер на нем спит, основной поток сигналит, воркер просыпается, сбрасывает сигнал, делает работу, и опять засыпает, или, если второй стоп-сигнал тоже активен — завершает работу. Второй сигнал — что воркеру надо завершиться — ставим его в сигнальное состояние, затем будим поток по первому сигналу, и ждём завершения.
В WinAPI для такого часто Event используют. В POSIX подход немного иной: обычно используют condition_variable. Смысл этого примитива в том, что каждый поток читает/меняет состояние внутри лока. После этого, можно делать такие вещи: если при чтении состояние не устраивает и нужно подождать другое, то делается wait. А другой поток может в локе ставить новое состояние и уведомлять того, кто ожидает с помощью notify.
Condition variable это очень удобная вещь, намного более удобная чем просто event в большинстве случаев. С помошью сondition variable можно не только флаги ждать/ставить, но и потокобезопасно работать с очередями задач и вообще с любым другим состоянием. Event же работает только с одним битом, что является иногда полезным, но не универсальным решением.
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, vopl, Вы писали:
V>>А вообще, лучше такое не на форуме спрашивать а самому вот тут смотреть https://en.cppreference.com/w/cpp/thread/thread, там номенклатура методов представлена, сразу видно что поток может и чего не может.
П>Да я смотрел, не совсем всё понятно.
П>Пораскинул, получается так: если мы хотим сделать изначально спящий поток, то просто конструируем без адреса функции: auto th = std::thread() (но на самом деле никакого потока не будет создано), если хотим сделать run(func), делаем th = std::thread(func), а вот чтобы при создании задать функцию потока, но отложить его запуск до лучших времён — такого нет
Это слишком частный кейс для того чтобы его обобщать в стандартной библиотеке. Его достаточно просто получить при помощи комбинирования имеющихся средств.
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, пффф, Вы писали:
П>Правильно ли я понимаю, что std::lock_guard и std::scoped_lock — аналогичны, но второй может лочить пачки разнородных объектов, а первый — только один mutex_type мьютекс?
да, lock_guard — частный случай scoped_lock. Также его можно считать deprecated с C++17
Здравствуйте, пффф, Вы писали:
П>Появились вопросы. В винде я обычно использовал CriticalSection — она позволяет уже залочившему потоку многократно делать лок без блокирования. Думал, std::mutex — это то, что мне нужно, но нет: If lock is called by a thread that already owns the mutex, the behavior is undefined: for example, the program may deadlock. А я не хочу парится об этом, и помнить, какая функция у меня лочит, а какая — нет.
std::recursive_mutex?
П>Далее. В винде есть Events или как-то так, могут быть в сигнальном и несигнальном состоянии. Вроде бы std::binary_semaphore похож на то, что мне нужно, но не уверен. Как получить на нем семантику SetEvent/ResetEvent/WaitFor?
Вот прям аналога Event ты вряд ли найдешь. Посмотри на conditional variable. Вот тебе прям статья на Хабре:
https://habr.com/ru/post/182626/
П>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
Нестатическая функция: это не один указатель, а два: на this и на функцию. Поэтому и нужен переходник.
П>ЗЗЫ Может, часть из того что нужно можно на атомиках сделать? Или это плохая идея?
Плохая, если не умеешь. А если умеешь, не задаешь вопросы.
Здравствуйте, пффф, Вы писали:
П>Да, точно, оно самое. Только вопрос такой — CriticalSection вроде как легковесный, спин лок, а мьютекс — это обычно сразу ядрёный вызов. В принципе, сейчас-то наплевать, но в целях саморазвития, есть что-то подобное лёгкое?
Оно в зависимости от реализации может быть легкое и не очень. Стандарт — он же описывает интерфейсы, а не как они реализованы. А как реализованы, очень зависит от платформы.
В целом, от нормальной реализации на "взрослой" платформе я бы ожидал, что то, что в принципе может быть сделано легким, будет сделано легким.
Здравствуйте, Pzz, Вы писали:
Pzz>Вот прям аналога Event ты вряд ли найдешь. Посмотри на conditional variable. Вот тебе прям статья на Хабре:
Pzz>https://habr.com/ru/post/182626/
Видел. Статья — говно
П>>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
Pzz>Нестатическая функция: это не один указатель, а два: на this и на функцию. Поэтому и нужен переходник.
Спасибо, КЭП
ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?
Здравствуйте, пффф, Вы писали:
П>ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?
Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.
C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...
Всем спасибо за советы, запилил, нормальненько работает.
Отдельно — в закромах нашлась книжка: Энтони Уильямс, "C++. Практика многопоточного программирования". Полистал её немного, несколько помогло подразобраться. Особо рекламировать не буду, но вроде толковая, мне помогла. Надо будет почитать повнимательнее
Здравствуйте, Pzz, Вы писали:
П>>ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?
Pzz>Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.
А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень
Pzz>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...
Здравствуйте, пффф, Вы писали:
Pzz>>Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.
П>А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень
Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.
В венде оно, кстати, не CriticalSection называется, а CRITICAL_SECTION. Шоб вырвиглаз наверняка.
Pzz>>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...
П>Дьявол — он в деталях
Здравствуйте, Pzz, Вы писали:
П>>А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень
Pzz>Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.
А готового spin lock'а у вас там не было, потому и писал своё
Pzz>В венде оно, кстати, не CriticalSection называется, а CRITICAL_SECTION. Шоб вырвиглаз наверняка.
Спасибо, я в курсе. Не хотел наносить глазную травму
Pzz>>>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...
П>>Дьявол — он в деталях
Pzz>Ну, я с бесами не общаюсь, тебе виднее.
Здравствуйте, vopl, Вы писали:
V>std::mutex обычно реализован через winapi-CriticalSection
Мне кажется последние годы обычно через slim reader/writer lock
Здравствуйте, пффф, Вы писали:
Pzz>>Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.
П>А готового spin lock'а у вас там не было, потому и писал своё
Spin lock хорош в ядре, где его захват попутно блокирует скедулер, и, тем самым, обеспечивает синхронизацию между ядрами процессора.
В user space толку от него заметно меньше. Если его кто-то держит, кому в данный момент процессора не хватило, а кто-то другой его хочет, так и будет крутиться, как угорелый, пока текущему владельцу опять не дадут поработать.
Да, я в курсе, что Microsoft считает, что при входе в критическую секцию есть смысл немного поболтаться на спинлоке в надежде, что вдруг повезет.
Здравствуйте, Pzz, Вы писали:
Pzz>>>Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.
П>>А готового spin lock'а у вас там не было, потому и писал своё
Pzz>Spin lock хорош в ядре, где его захват попутно блокирует скедулер, и, тем самым, обеспечивает синхронизацию между ядрами процессора.
Это не отменяет того факта, что спин лока в линупсе долго не было
Pzz>В user space толку от него заметно меньше. Если его кто-то держит, кому в данный момент процессора не хватило, а кто-то другой его хочет, так и будет крутиться, как угорелый, пока текущему владельцу опять не дадут поработать.
Есть статистика? Или так, чисто побалаболить?
Спинлок здорового человека засыпает на мьютексе после некоторого количества циклов. Как угорелый крутится только спин лок курильщика, и, возможно, линупсоида
Pzz>Да, я в курсе, что Microsoft считает, что при входе в критическую секцию есть смысл немного поболтаться на спинлоке в надежде, что вдруг повезет.
Если потрогать пару переменных — то несомненно, это дешевле, чем сразу в ядро нырять. А если что-то долгое — так у винды можно wait'ить почти на любом хэндле, и тут опять мьютексы не нужны. Это просто POSIX ущербный
Вот этого товарища послущай https://www.youtube.com/watch?v=NawpxG81RRk
Всего видюх по 10-20 минут — самое оно для начала параллельности в С++
Все очень просто и понятно.
И про mutex, и про lock_guard, и про unique_guard, про recursive_mutex
И про передачу параметров с возвратом результатов, и про вызов методов.
В общем — абсолютно необходимый минимум.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Здравствуйте, пффф, Вы писали:
П>Здравствуйте, Pzz, Вы писали:
П>>>А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень
Pzz>>Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.
П>А готового spin lock'а у вас там не было, потому и писал своё
А зачем?
В Linux mutex реализован через атомарные переменные,
то есть там несколько циклов происходит попытка "захватить" блокировку,
по сути "spin lock", а только потом поток засыпает.
По идее там все выверено по количеству итераций "spin lock" перед засыпанием,
чтобы зря циклы CPU не жечь в "busy loop" и не делать лишних системных вызовов
если lock/unlock защищают небольшой участок кода.
Здравствуйте, Zhendos, Вы писали:
Z>В Linux mutex реализован через атомарные переменные, Z>то есть там несколько циклов происходит попытка "захватить" блокировку, Z>по сути "spin lock", а только потом поток засыпает.
Ты токашо описал виндовый Critical Section.
Z>По идее там все выверено по количеству итераций "spin lock" перед засыпанием,
И оно само угадывает какой длительности код под локом чтоб проспинать ровно сколько нужно, ага!
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
CC>Здравствуйте, Maniacal, Вы писали:
M>>я про стандарты. CC>Posix это не стандарт а говно мамонта.
POSIX (англ. Portable Operating System Interface — переносимый интерфейс операционных систем) — набор стандартов, описывающих интерфейсы между операционной системой и прикладной программой (системный API), библиотеку языка C и набор приложений и их интерфейсов. Стандарт создан для обеспечения совместимости различных UNIX-подобных операционных систем и переносимости прикладных программ на уровне исходного кода, но может быть использован и для не-Unix систем.
Серия стандартов POSIX была разработана комитетом 1003 IEEE. Международная организация по стандартизации (ISO) совместно c Международной электротехнической комиссией (IEC) приняла стандарт POSIX под названием ISO/IEC 9945[2]. Версии стандарта POSIX являются основой соответствующих версий стандарта Single UNIX Specification. Стандарт POSIX определяет интерфейс операционной системы, а соответствие стандарту Single UNIX Specification определяет реализацию интерфейса и позволяет операционным системам использовать торговую марку UNIX[3].
Т.е. SysV и BSD тоже не стандарты? Зачем же они тогда в линуксах поддержаны. Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили.
Здравствуйте, Maniacal, Вы писали:
M>Зачем же они тогда в линуксах поддержаны.
Это ты у пингвина спрашивай
M> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили.
И правильно сделали, куда вменяемее получилось.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
M>> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили. CC>И правильно сделали, куда вменяемее получилось.
Но потом всё равно пришлось притаскивать к себе UTF-8, ANSI escape sequences, симлинки и прочие достижения цивилизованного мира. Куда деваться с подводной лодки?
Хотя, наверное, asynchronous IO в NT более лучше сделан, чем в Unix. Что, собственно, неудивительно, учитывая разницу во времени между их появлением.
Здравствуйте, ?, Вы писали:
CC>>И правильно сделали, куда вменяемее получилось.
?>Но потом всё равно пришлось притаскивать к себе UTF-8
Это в каком месте то? Везде со времён NT используется UCS2
?> ANSI escape sequences
Опять таки где?
?> симлинки
Банально расширили Reparse points
?> и прочие достижения цивилизованного мира.
А именно?
?>Что, собственно, неудивительно, учитывая разницу во времени между их появлением.
В основном потому что им не надо было запихивать себя в прокрустово ложе откровенно устаревших интерфейсов.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, CreatorCray, Вы писали:
M>> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили. CC>И правильно сделали, куда вменяемее получилось.
Согласен, но когда под Линух пишешь или кросс-платформенное решение, то никак не помогает. Если только собственные библиотеки (или чужие) юзать, которые в зависимости от платформы компилируют одну свою часть реализации или другую.
у Винды очень тесная интеграция GUI и API те же messages. В *nix универсальный и, потому, более тормозной GUI.
Здравствуйте, Maniacal, Вы писали:
M>Согласен, но когда под Линух пишешь или кросс-платформенное решение, то никак не помогает.
И не должно.
M>В *nix универсальный и, потому, более тормозной GUI.
Всё универсальное это мешок компромиссов, в итоге работает одинаково хреново на всём.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Здравствуйте, пффф, Вы писали:
П>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?
Полистал ответы, не увидел вариантов без "переходника". Может, пропустил.
Переходник не нужен. Вот:
struct A
{
void run(int, const std::string&) { /*do stuff*/ }
};
int main()
{
A a;
std::thread t{&A::run, &a, 1, ""};
t.join();
}
Здравствуйте, пффф, Вы писали:
П>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы
В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.
В плюсах есть нечто подобное?
Здравствуйте, gyraboo, Вы писали:
g> В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.
Типа, кооперативную многозадачность переизобрели что-ли?
Здравствуйте, gyraboo, Вы писали:
G>Здравствуйте, пффф, Вы писали:
П>>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы
G>В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы. G>В плюсах есть нечто подобное?
Здравствуйте, gyraboo, Вы писали: G>В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы. G>В плюсах есть нечто подобное?
Так можно было и на обычном C писать (с некоторыми оговорками):
Здравствуйте, gyraboo, Вы писали:
G>Здравствуйте, Zhendos, Вы писали:
Z>>С каких пор реактивность модная? Вроде уже много Z>>кто стал отказываться из-зак "calback hell" в пользу Z>>"async".
G>И что же, всё богатство конвейерных операторов реактивных потоков тоже в топку?
А зачем все это богатство нужно если можно просто написать несколько библиотечных "async" функций
или просто "if/while"?
Здравствуйте, Zhendos, Вы писали:
G>>И что же, всё богатство конвейерных операторов реактивных потоков тоже в топку?
Z>А зачем все это богатство нужно если можно просто написать несколько библиотечных "async" функций Z>или просто "if/while"?
Ты мне глаза открыл. Можно либо написать самому, если оно реюзается, оформить в виде библиотеки, тем более что код async — он нагляднее. Спасибо.
Либо вообще под вопросом их использование, раньше без них как-то жили, и ничего.
П>>Ну вот и путают. Классический мьютекс — это средство межпроцессного взаимодействия M>Нет. Только именованные.
Че ето вдруг. DuplicateHandle или отнаследованные хэндлы мутексов так же прекрасно работают между разными процессами.
НО проблема тут не в С++, а в том что изначальная* структура ядра винды была спроектированна умными людьми — с ортогональной системой типов объектов ядра, а юникс делался по принципу 'ну че пишем очередную версию червяка Морриса и нам нужны средства межпроцессной синхронизации, ну давайте запилим sem_open'
* Теперь то конечно уже и винда г..но — то есть плоды противоестественной любви микрософта и линукса в недавнем прошлом...
Как много веселых ребят, и все делают велосипед...