Re[6]: Многопоточность в современных плюсиках
От: пффф  
Дата: 06.02.23 18:55
Оценка:
Здравствуйте, vopl, Вы писали:

V>А вообще, лучше такое не на форуме спрашивать а самому вот тут смотреть https://en.cppreference.com/w/cpp/thread/thread, там номенклатура методов представлена, сразу видно что поток может и чего не может.


Да я смотрел, не совсем всё понятно.

Пораскинул, получается так: если мы хотим сделать изначально спящий поток, то просто конструируем без адреса функции: auto th = std::thread() (но на самом деле никакого потока не будет создано), если хотим сделать run(func), делаем th = std::thread(func), а вот чтобы при создании задать функцию потока, но отложить его запуск до лучших времён — такого нет
Re[6]: Многопоточность в современных плюсиках
От: пффф  
Дата: 06.02.23 19:41
Оценка: :))
Здравствуйте, vopl, Вы писали:

П>>В винде мьютекс можно шарить между процессами, а в плюсиках как с этим? Или такого нет?

V>Нет.

Ну вот и путают. Классический мьютекс — это средство межпроцессного взаимодействия
Re[3]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 06.02.23 20:19
Оценка:
Здравствуйте, пффф, Вы писали:

П>CriticalSection вроде как легковесный, спин лок

Не, он сначала "спинает в гробу" а если спинал слишком долго тогда взыхает и переходит к более тяжёлому ожиданию.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[4]: Многопоточность в современных плюсиках
От: пффф  
Дата: 06.02.23 20:21
Оценка:
Здравствуйте, CreatorCray, Вы писали:


П>>CriticalSection вроде как легковесный, спин лок

CC>Не, он сначала "спинает в гробу" а если спинал слишком долго тогда взыхает и переходит к более тяжёлому ожиданию.

Да, спасибо, я в курсе, как и о том, что начиная с XP спин каунтер можно задавать
Re[2]: Многопоточность в современных плюсиках
От: Aquilaware  
Дата: 07.02.23 03:44
Оценка:
Здравствуйте, пффф, Вы писали:

П>Мне надо сделать поток и два сигнала. Один сигнал — что для потока есть работа, воркер на нем спит, основной поток сигналит, воркер просыпается, сбрасывает сигнал, делает работу, и опять засыпает, или, если второй стоп-сигнал тоже активен — завершает работу. Второй сигнал — что воркеру надо завершиться — ставим его в сигнальное состояние, затем будим поток по первому сигналу, и ждём завершения.


В WinAPI для такого часто Event используют. В POSIX подход немного иной: обычно используют condition_variable. Смысл этого примитива в том, что каждый поток читает/меняет состояние внутри лока. После этого, можно делать такие вещи: если при чтении состояние не устраивает и нужно подождать другое, то делается wait. А другой поток может в локе ставить новое состояние и уведомлять того, кто ожидает с помощью notify.

Вот тут пример есть.

Condition variable это очень удобная вещь, намного более удобная чем просто event в большинстве случаев. С помошью сondition variable можно не только флаги ждать/ставить, но и потокобезопасно работать с очередями задач и вообще с любым другим состоянием. Event же работает только с одним битом, что является иногда полезным, но не универсальным решением.
Re[7]: Многопоточность в современных плюсиках
От: vopl Россия  
Дата: 07.02.23 05:23
Оценка:
Здравствуйте, пффф, Вы писали:

П>Здравствуйте, vopl, Вы писали:


V>>А вообще, лучше такое не на форуме спрашивать а самому вот тут смотреть https://en.cppreference.com/w/cpp/thread/thread, там номенклатура методов представлена, сразу видно что поток может и чего не может.


П>Да я смотрел, не совсем всё понятно.


П>Пораскинул, получается так: если мы хотим сделать изначально спящий поток, то просто конструируем без адреса функции: auto th = std::thread() (но на самом деле никакого потока не будет создано), если хотим сделать run(func), делаем th = std::thread(func), а вот чтобы при создании задать функцию потока, но отложить его запуск до лучших времён — такого нет


Это слишком частный кейс для того чтобы его обобщать в стандартной библиотеке. Его достаточно просто получить при помощи комбинирования имеющихся средств.
#include <functional>
#include <thread>
#include <iostream>

struct DelayedStartThread : std::thread
{
    template <class F>
    DelayedStartThread(F&& f)
        : std::thread{}
        , _f{std::forward<F>(f)}
    {
    }

    void start()
    {
        std::thread::operator=(std::thread{move(_f)});
    }

    std::function<void()> _f;
};

int main()
{
    DelayedStartThread dst{[]{
        std::cout << "started" << std::endl;
    }};
    std::cout << "not started yet" << std::endl;
    dst.start();
    dst.join();
    return 0;
}
Re[7]: Многопоточность в современных плюсиках
От: Maniacal Россия  
Дата: 07.02.23 06:29
Оценка:
Здравствуйте, пффф, Вы писали:

П>Ну вот и путают. Классический мьютекс — это средство межпроцессного взаимодействия


Нет. Только именованные. В Линухах именованные только семафоры бывают, ЕМНИП. В Винде всё можно именовать. А семофоры вообще в std появились с c++20

Ещё норм вещь std::condition_variable, в линухах искаропки есть в стандарте POSIX, SysV или BSD, не помню уже.
Отредактировано 07.02.2023 6:35 Maniacal . Предыдущая версия . Еще …
Отредактировано 07.02.2023 6:31 Maniacal . Предыдущая версия .
Re[8]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 07.02.23 07:03
Оценка:
Здравствуйте, Maniacal, Вы писали:

M>Ещё норм вещь std::condition_variable, в линухах искаропки есть в стандарте POSIX, SysV или BSD, не помню уже.

https://learn.microsoft.com/en-us/windows/win32/sync/condition-variables
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[9]: Многопоточность в современных плюсиках
От: Maniacal Россия  
Дата: 07.02.23 07:22
Оценка: :)
Здравствуйте, CreatorCray, Вы писали:

CC>Здравствуйте, Maniacal, Вы писали:


M>>Ещё норм вещь std::condition_variable, в линухах искаропки есть в стандарте POSIX, SysV или BSD, не помню уже.

CC>https://learn.microsoft.com/en-us/windows/win32/sync/condition-variables

Это WinAPI, майкрософтовская реализаци со своим блекджеком и девушками с пониженной социальной ответственностью, я про стандарты.
Re[2]: Многопоточность в современных плюсиках
От: sergii.p  
Дата: 07.02.23 10:59
Оценка:
Здравствуйте, пффф, Вы писали:

П>Здравствуйте, пффф, Вы писали:


П>Правильно ли я понимаю, что std::lock_guard и std::scoped_lock — аналогичны, но второй может лочить пачки разнородных объектов, а первый — только один mutex_type мьютекс?


да, lock_guard — частный случай scoped_lock. Также его можно считать deprecated с C++17
Re[2]: Многопоточность в современных плюсиках
От: B0FEE664  
Дата: 07.02.23 12:59
Оценка:
Здравствуйте, пффф, Вы писали:

П>А что-то типа виндового Event с авторесетом есть?

здесь
Автор: B0FEE664
Дата: 29.09.14
И каждый день — без права на ошибку...
Re: Многопоточность в современных плюсиках
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.02.23 20:32
Оценка:
Здравствуйте, пффф, Вы писали:

П>Появились вопросы. В винде я обычно использовал 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 и на функцию. Поэтому и нужен переходник.

П>ЗЗЫ Может, часть из того что нужно можно на атомиках сделать? Или это плохая идея?


Плохая, если не умеешь. А если умеешь, не задаешь вопросы.
Re[3]: Многопоточность в современных плюсиках
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.02.23 20:34
Оценка:
Здравствуйте, пффф, Вы писали:

П>Да, точно, оно самое. Только вопрос такой — CriticalSection вроде как легковесный, спин лок, а мьютекс — это обычно сразу ядрёный вызов. В принципе, сейчас-то наплевать, но в целях саморазвития, есть что-то подобное лёгкое?


Оно в зависимости от реализации может быть легкое и не очень. Стандарт — он же описывает интерфейсы, а не как они реализованы. А как реализованы, очень зависит от платформы.

В целом, от нормальной реализации на "взрослой" платформе я бы ожидал, что то, что в принципе может быть сделано легким, будет сделано легким.
Re[2]: Многопоточность в современных плюсиках
От: пффф  
Дата: 07.02.23 20:35
Оценка: 1 (1)
Здравствуйте, Pzz, Вы писали:

Pzz>Вот прям аналога Event ты вряд ли найдешь. Посмотри на conditional variable. Вот тебе прям статья на Хабре:


Pzz>https://habr.com/ru/post/182626/


Видел. Статья — говно


П>>Ну и сам std::thread. Что-то не понятно, можно ли и как ему подсунуть нестатическую функцию класса. В винде и в POSIX решалось через статический переходник, адрес объекта передавался через void* параметр. Тут аналогично надо приседать или есть варианты получше?


Pzz>Нестатическая функция: это не один указатель, а два: на this и на функцию. Поэтому и нужен переходник.


Спасибо, КЭП


ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?
Re[3]: Многопоточность в современных плюсиках
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.02.23 20:39
Оценка:
Здравствуйте, пффф, Вы писали:

П>ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?


Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.

C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...
Re: Многопоточность в современных плюсиках
От: пффф  
Дата: 07.02.23 20:40
Оценка:
Здравствуйте, пффф, Вы писали:

Всем спасибо за советы, запилил, нормальненько работает.

Отдельно — в закромах нашлась книжка: Энтони Уильямс, "C++. Практика многопоточного программирования". Полистал её немного, несколько помогло подразобраться. Особо рекламировать не буду, но вроде толковая, мне помогла. Надо будет почитать повнимательнее
Re[4]: Многопоточность в современных плюсиках
От: пффф  
Дата: 07.02.23 20:46
Оценка:
Здравствуйте, Pzz, Вы писали:

П>>ЗЫ Ты ж не плюсовик вроде совсем, что тогда советы по плюсам даёшь?


Pzz>Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.


А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень


Pzz>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...


Дьявол — он в деталях
Re[5]: Многопоточность в современных плюсиках
От: Pzz Россия https://github.com/alexpevzner
Дата: 07.02.23 20:49
Оценка: -1
Здравствуйте, пффф, Вы писали:

Pzz>>Плюсовик-не плюсовик, а про рекурсивный мьютекс сам знаю, а не на форуме спрашиваю.


П>А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень


Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.

В венде оно, кстати, не CriticalSection называется, а CRITICAL_SECTION. Шоб вырвиглаз наверняка.

Pzz>>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...


П>Дьявол — он в деталях


Ну, я с бесами не общаюсь, тебе виднее.
Re[6]: Многопоточность в современных плюсиках
От: пффф  
Дата: 07.02.23 20:54
Оценка: 1 (1) -1
Здравствуйте, Pzz, Вы писали:

П>>А я под виндой использовал CriticalSection, а под линупсом — сам аналог её писал, и мне как-то пофигу было, какие где мьютексы, где рекурсивные, а где — не очень


Pzz>Ну молодец. А знал бы, как это правильно называется, воспользовался бы готовым.


А готового spin lock'а у вас там не было, потому и писал своё


Pzz>В венде оно, кстати, не CriticalSection называется, а CRITICAL_SECTION. Шоб вырвиглаз наверняка.


Спасибо, я в курсе. Не хотел наносить глазную травму


Pzz>>>C++-ная многопоточка очень напоминает по сути своей POSIX threads, оформленные в плюсовом стиле. А про POSIX threads мне доводилось кое-чего слышать...


П>>Дьявол — он в деталях


Pzz>Ну, я с бесами не общаюсь, тебе виднее.


С деталями — тоже?
Re[4]: Многопоточность в современных плюсиках
От: Константин Черногория  
Дата: 07.02.23 21:39
Оценка:
Здравствуйте, vopl, Вы писали:

V>std::mutex обычно реализован через winapi-CriticalSection

Мне кажется последние годы обычно через slim reader/writer lock
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.