Надо немножко многопоточности добавить в прогу, решил использовать стандартное плюсовое, которое недавно завезли. Раньше работал в основном с виндовыми потоками и объектами синхронизации, но немного и 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, в живую все это увидеть можно примерно тут
П>Могли бы отдельно спин-лок класс сделать, а не путать народ.
Да вроде никто и не путается, ты первый жалуешся
П>В винде мьютекс можно шарить между процессами, а в плюсиках как с этим? Или такого нет?
Нет.