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

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


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


Spin lock хорош в ядре, где его захват попутно блокирует скедулер, и, тем самым, обеспечивает синхронизацию между ядрами процессора.

В user space толку от него заметно меньше. Если его кто-то держит, кому в данный момент процессора не хватило, а кто-то другой его хочет, так и будет крутиться, как угорелый, пока текущему владельцу опять не дадут поработать.

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

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


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


Pzz>Spin lock хорош в ядре, где его захват попутно блокирует скедулер, и, тем самым, обеспечивает синхронизацию между ядрами процессора.


Это не отменяет того факта, что спин лока в линупсе долго не было


Pzz>В user space толку от него заметно меньше. Если его кто-то держит, кому в данный момент процессора не хватило, а кто-то другой его хочет, так и будет крутиться, как угорелый, пока текущему владельцу опять не дадут поработать.


Есть статистика? Или так, чисто побалаболить?

Спинлок здорового человека засыпает на мьютексе после некоторого количества циклов. Как угорелый крутится только спин лок курильщика, и, возможно, линупсоида


Pzz>Да, я в курсе, что Microsoft считает, что при входе в критическую секцию есть смысл немного поболтаться на спинлоке в надежде, что вдруг повезет.


Если потрогать пару переменных — то несомненно, это дешевле, чем сразу в ядро нырять. А если что-то долгое — так у винды можно wait'ить почти на любом хэндле, и тут опять мьютексы не нужны. Это просто POSIX ущербный
Re[10]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 07.02.23 23:38
Оценка: 1 (1) +1 -1
Здравствуйте, Maniacal, Вы писали:

M>я про стандарты.

Posix это не стандарт а говно мамонта.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Многопоточность в современных плюсиках
От: LaptevVV Россия  
Дата: 08.02.23 04:59
Оценка:
Вот этого товарища послущай
https://www.youtube.com/watch?v=NawpxG81RRk
Всего видюх по 10-20 минут — самое оно для начала параллельности в С++
Все очень просто и понятно.
И про mutex, и про lock_guard, и про unique_guard, про recursive_mutex
И про передачу параметров с возвратом результатов, и про вызов методов.
В общем — абсолютно необходимый минимум.
Хочешь быть счастливым — будь им!
Без булдырабыз!!!
Re[7]: Многопоточность в современных плюсиках
От: Zhendos  
Дата: 08.02.23 08:58
Оценка:
Здравствуйте, пффф, Вы писали:

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


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


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


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


А зачем?

В Linux mutex реализован через атомарные переменные,
то есть там несколько циклов происходит попытка "захватить" блокировку,
по сути "spin lock", а только потом поток засыпает.
По идее там все выверено по количеству итераций "spin lock" перед засыпанием,
чтобы зря циклы CPU не жечь в "busy loop" и не делать лишних системных вызовов
если lock/unlock защищают небольшой участок кода.
Re[8]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 08.02.23 17:46
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>В Linux mutex реализован через атомарные переменные,

Z>то есть там несколько циклов происходит попытка "захватить" блокировку,
Z>по сути "spin lock", а только потом поток засыпает.
Ты токашо описал виндовый Critical Section.

Z>По идее там все выверено по количеству итераций "spin lock" перед засыпанием,

И оно само угадывает какой длительности код под локом чтоб проспинать ровно сколько нужно, ага!
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[11]: Многопоточность в современных плюсиках
От: Maniacal Россия  
Дата: 09.02.23 10:07
Оценка:
Здравствуйте, 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 лет назад не признали, свой блэкджек замутили.
Re[12]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 09.02.23 21:24
Оценка:
Здравствуйте, Maniacal, Вы писали:

M>Зачем же они тогда в линуксах поддержаны.

Это ты у пингвина спрашивай

M> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили.

И правильно сделали, куда вменяемее получилось.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[13]: Многопоточность в современных плюсиках
От: σ  
Дата: 09.02.23 22:49
Оценка:
M>> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили.
CC>И правильно сделали, куда вменяемее получилось.
Но потом всё равно пришлось притаскивать к себе UTF-8, ANSI escape sequences, симлинки и прочие достижения цивилизованного мира. Куда деваться с подводной лодки?
Хотя, наверное, asynchronous IO в NT более лучше сделан, чем в Unix. Что, собственно, неудивительно, учитывая разницу во времени между их появлением.
Отредактировано 09.02.2023 22:50 σ . Предыдущая версия .
Re[14]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 09.02.23 23:30
Оценка:
Здравствуйте, ?, Вы писали:

CC>>И правильно сделали, куда вменяемее получилось.

?>Но потом всё равно пришлось притаскивать к себе UTF-8
Это в каком месте то? Везде со времён NT используется UCS2

?> ANSI escape sequences
Опять таки где?

?> симлинки
Банально расширили Reparse points

?> и прочие достижения цивилизованного мира.
А именно?

?>Что, собственно, неудивительно, учитывая разницу во времени между их появлением.
В основном потому что им не надо было запихивать себя в прокрустово ложе откровенно устаревших интерфейсов.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re[13]: Многопоточность в современных плюсиках
От: Maniacal Россия  
Дата: 10.02.23 07:24
Оценка:
Здравствуйте, CreatorCray, Вы писали:

M>> Да, мелкомягкие их ещё 20 лет назад не признали, свой блэкджек замутили.

CC>И правильно сделали, куда вменяемее получилось.

Согласен, но когда под Линух пишешь или кросс-платформенное решение, то никак не помогает. Если только собственные библиотеки (или чужие) юзать, которые в зависимости от платформы компилируют одну свою часть реализации или другую.
у Винды очень тесная интеграция GUI и API те же messages. В *nix универсальный и, потому, более тормозной GUI.
Re[14]: Многопоточность в современных плюсиках
От: CreatorCray  
Дата: 11.02.23 00:34
Оценка: +1
Здравствуйте, Maniacal, Вы писали:

M>Согласен, но когда под Линух пишешь или кросс-платформенное решение, то никак не помогает.

И не должно.

M>В *nix универсальный и, потому, более тормозной GUI.

Всё универсальное это мешок компромиссов, в итоге работает одинаково хреново на всём.
... << RSDN@Home 1.3.110 alpha 5 rev. 62>>
Забанили по IP, значит пора закрыть эту страницу.
Всем пока
Re: Многопоточность в современных плюсиках
От: serg_joker Украина  
Дата: 04.03.23 21:57
Оценка: :)
Здравствуйте, пффф, Вы писали:

П>Ну и сам 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();
}
Re: Многопоточность в современных плюсиках
От: gyraboo  
Дата: 05.03.23 06:43
Оценка:
Здравствуйте, пффф, Вы писали:

П>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы


В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.
В плюсах есть нечто подобное?
Отредактировано 05.03.2023 7:42 gyraboo . Предыдущая версия .
Re[2]: Многопоточность в современных плюсиках
От: rudzuk  
Дата: 05.03.23 09:47
Оценка: +1
Здравствуйте, gyraboo, Вы писали:

g> В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.


Типа, кооперативную многозадачность переизобрели что-ли?
avalon/3.0.2
Re[2]: Многопоточность в современных плюсиках
От: Zhendos  
Дата: 05.03.23 12:01
Оценка:
Здравствуйте, gyraboo, Вы писали:

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


П>>ЗЫ Тыщу лет многопоточки не писал, да и в новых плюсиках не очень ориентируюсь, звиняйте за глупые вопросы


G>В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.

G>В плюсах есть нечто подобное?

С каких пор реактивность модная? Вроде уже много
кто стал отказываться из-за "calback hell" в пользу
"async". И в C++ эта фича есть в C++20: https://en.cppreference.com/w/cpp/language/coroutines
Отредактировано 06.03.2023 6:29 Zhendos . Предыдущая версия .
Re[2]: Многопоточность в современных плюсиках
От: kov_serg Россия  
Дата: 05.03.23 12:10
Оценка:
Здравствуйте, gyraboo, Вы писали:

G>В джаве сейчас моднявая тема — реактивность. Она предлагает отказаться от потоков в пользу неблокирующего кода, работающего на ограниченном количестве потоков (т.н. рельсах). Профит в том, что переключение контекста потоков очень дорогое, а тут переключения нет, поэтому нагрузку держит бОльшую. Но писать код реактивных стримов надо так, чтобы он был неблокирующим, иначе он залочит рельсу и застопорит конвейер рельсы.

G>В плюсах есть нечто подобное?

Так можно было и на обычном C писать (с некоторыми оговорками):
  track-fn.h
/* track-fn.h */
#pragma once

enum TrackConsts { track_no_limit=-1, track_start_line=0, track_end_line=-1 };
enum TrackResultCodes { track_rc_done=0, track_rc_active=1, track_rc_int=2 };

typedef struct Track { int line,limit; } Track;

#define TRACK_RESET(v) { Track *_track=(v); _track->line=0; _track->limit=1; }
#define TRACK_SET_LIMIT(track,n) { (track)->limit=n; }

#define TRACK_BEGIN(v) { Track *_track=(v); track_begin: \
    switch(_track->line) { default: case 0: TRACK_POINT
#define TRACK_POINT { case __LINE__: _track->line=__LINE__; \
    if (_track->limit>=0 && !_track->limit--) { _track->limit=1; return 1; } }
#define TRACK_END   track_end: case -1: _track->line=-1; return 0; } \
    track_interrupt: return 2; }

#define TRACK_END_R track_end: _track->line=-1; _track->limit=1; return 0; } \
    track_interrupt: return 2; }

#define TRACK_REPEAT_LAST goto track_begin;
#define TRACK_LEAVE       goto track_end;
#define TRACK_INTERRUPT   goto track_interrupt;

#define TRACK_CALL(fn,state) { int rc; \
    for(fn##_reset(state);0!=(rc=fn(state));) { \
        if (rc==track_rc_int) { TRACK_INTERRUPT } else { TRACK_POINT } \
    }}
/* tracks.c */
#include <stdio.h>
#include "track-fn.h"

typedef struct {
    Track track[1];
    int in0;
} fn1_state;
void fn1_reset(fn1_state *self) { TRACK_RESET(self->track); }

int fn1(fn1_state *self) {
    TRACK_BEGIN(self->track)
        printf("\tfn1.1\t%d\n",self->in0);
        TRACK_POINT
        printf("\tfn1.2\t%d\n",self->in0);
    TRACK_END
}

typedef struct {
    Track track[1];
    fn1_state fn1[1]; 
    int i;
} fn2_state;
void fn2_reset(fn2_state *self) { TRACK_RESET(self->track); }

int fn2(fn2_state *self) {
    TRACK_BEGIN(self->track)
        printf("fn2.1\n");
        TRACK_POINT
        for(self->i=1;self->i<=3;self->i++) {
            self->fn1->in0=self->i; /* function input arg */
            TRACK_CALL(fn1,self->fn1)
        }
        TRACK_POINT 
        printf("fn2.2\n");
    TRACK_END
}

int main(int argc, char const *argv[]) {    
    fn2_state s[1];
    fn2_reset(s);

    s->track->limit=3; fn2(s);
    printf("--\n");
    s->track->limit=track_no_limit; fn2(s);
    return 0;
}

А в плюсах только C++20 добавили коротины, но слегка через жопу как обычно.
  cpp20.cpp
// g++-10 -std=c++20 -fcoroutines cpp20.cpp && ./a.out
#include <coroutine>
#include <iostream>

struct resumable {
    struct promise_type {
        using coro_handle = std::coroutine_handle<promise_type>;
        auto get_return_object() { return coro_handle::from_promise(*this); }
        auto initial_suspend() { return std::suspend_always{}; }
        auto final_suspend() noexcept { return std::suspend_always{}; }
        void return_void() {}
        void unhandled_exception() { std::terminate(); }
    };
    using coro_handle = std::coroutine_handle<promise_type>;
    resumable(coro_handle handle) : handle(handle) {}
    bool resume() { if (!handle.done()) handle.resume(); return !handle.done(); }
    ~resumable() { if (handle) handle.destroy(); }
private:
    coro_handle handle;
};

resumable fn1() {
    std::cout<<"Hello"<<std::endl;
    co_await std::suspend_always{};
    std::cout<<"World"<<std::endl;
    co_await std::suspend_always{};
    std::cout<<"!!!"<<std::endl;
}

int main(int argc, char const *argv[]) {
    auto t=fn1();
    t.resume();
    t.resume();
    t.resume();
    return 0;
}
Re[3]: Многопоточность в современных плюсиках
От: gyraboo  
Дата: 05.03.23 16:59
Оценка:
Здравствуйте, Zhendos, Вы писали:

Z>С каких пор реактивность модная? Вроде уже много

Z>кто стал отказываться из-зак "calback hell" в пользу
Z>"async".

И что же, всё богатство конвейерных операторов реактивных потоков тоже в топку?
Re[4]: Многопоточность в современных плюсиках
От: Zhendos  
Дата: 06.03.23 06:31
Оценка:
Здравствуйте, gyraboo, Вы писали:

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


Z>>С каких пор реактивность модная? Вроде уже много

Z>>кто стал отказываться из-зак "calback hell" в пользу
Z>>"async".

G>И что же, всё богатство конвейерных операторов реактивных потоков тоже в топку?


А зачем все это богатство нужно если можно просто написать несколько библиотечных "async" функций
или просто "if/while"?
Re[5]: Многопоточность в современных плюсиках
От: gyraboo  
Дата: 06.03.23 07:10
Оценка:
Здравствуйте, Zhendos, Вы писали:

G>>И что же, всё богатство конвейерных операторов реактивных потоков тоже в топку?


Z>А зачем все это богатство нужно если можно просто написать несколько библиотечных "async" функций

Z>или просто "if/while"?

Ты мне глаза открыл. Можно либо написать самому, если оно реюзается, оформить в виде библиотеки, тем более что код async — он нагляднее. Спасибо.
Либо вообще под вопросом их использование, раньше без них как-то жили, и ничего.
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.