powered by simpleCommunicator - 2.0.58     © 2025 Programmizd 02
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Форумы / C++ [игнор отключен] [закрыт для гостей] / Небольшой вопрос про std::thread
25 сообщений из 82, страница 1 из 4
Небольшой вопрос про std::thread
    #40007063
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Я прошу прощения, компилировать не буду, могу в синтаксисе ошибиться. Но суть будет понятна.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int aaa = 1;

void doWork()
{
    aaa++;
}

void main()
{
    ++aaa;
    std::thread(doWork).join();
    std::cout << aaa;
}


Вопрос: является ли приложение потокобезопасным?
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007064
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravявляется ли приложение потокобезопасным?

В данном приложении всего один поток, так что, да, оно потокобезопасное за отсутствием
многопоточности. Было бы потоков больше - пришлось бы обсуждать последствия возможного
получения не тех значений, которые ожидались.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007065
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov,

Почему один поток? Я же создаю объект потока... Не, чисто технически оно могло бы выродится в
однопоточное, но я не представляю как оптимизатор мог бы так лихо отработать.

PS: Я немного доработал первый пост.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007066
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Почему один поток?

Потому что первый поток стоит и совсем ничего не делает пока не завершится второй.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007067
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov
petrav
Почему один поток?

Потому что первый поток стоит и совсем ничего не делает пока не завершится второй.

Да, но как у нас там? У ядер процессора свой/личный кэш верхнего уровня. У каждого потока
свой набор регистров (сохраняемый в контексте потока). Каким образом они тут синхронизированы?
И синхронизированы ли? В данном коде.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007069
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravУ ядер процессора свой/личный кэш верхнего уровня. У каждого потока
свой набор регистров (сохраняемый в контексте потока).

И всё это совершенно не влияет на ответ: в данной программе одновременно работает только
один поток, она не многопоточная.
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007070
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Dimitry Sibiryakov
пропущено...

Потому что первый поток стоит и совсем ничего не делает пока не завершится второй.

Да, но как у нас там? У ядер процессора свой/личный кэш верхнего уровня. У каждого потока
свой набор регистров (сохраняемый в контексте потока). Каким образом они тут синхронизированы?
И синхронизированы ли? В данном коде.

В кэш других потоков оно попасть не успело
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007072
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravУ ядер процессора свой/личный кэш верхнего уровня. У каждого потока
свой набор регистров (сохраняемый в контексте потока).

И всё это совершенно не влияет на ответ: в данной программе одновременно работает только
один поток, она не многопоточная.

А если я сейчас соберу эту программу и в Process Explorer увижу два потока?
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007074
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravА если я сейчас соберу эту программу и в Process Explorer увижу два потока?

Увидишь. Но толку-то?..
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007077
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravА если я сейчас соберу эту программу и в Process Explorer увижу два потока?

Увидишь. Но толку-то?..

Представим себе предположительное исполнение потоков. Условие: потоки исполняются на
разных ядрах и регистры у них, понятно, разные.

Поток main():

- Увеличил значение "aaa" до двух и сохранил это в своём контексте (регистре).
- Запустил поток doWork().
- Вывел на печать значение "aaa" сохранённое в контексте этого потока. Т.е. два!

Поток doWork():

- Увеличил значение "aaa" до двух и сохранил это в своём контексте (регистре).
- И потерял значение.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007078
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Вопрос: является ли приложение потокобезопасным?

Является 100%
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007080
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravПредставим себе предположительное исполнение потоков.

Ну представили. Да, такое возможно. А дальше-то что? Наличие гонок потоков не делает код
потокоопасным если результат этих гонок никого не волнует.

Ну а если волнует, тогда да: atomic_int тебе в руки. В некоторых случаях можно и volatile
обойтись. А в некоторых - нужна критическая секция/мутекс.

"Каждый выбирает по себе." (с)
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007083
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravПредставим себе предположительное исполнение потоков.

Ну представили. Да, такое возможно. А дальше-то что?
Если такое возможно, то приложение не потокобезопасно.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007084
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Обычно спрашивают, я вляется ли класс или метод потокобезопасным..
То есть можно ли их поместить в поток безопасно.
Но у Сишников наверно все по другому)
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007085
Dimitry Sibiryakov
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petravЕсли такое возможно, то приложение не потокобезопасно.

В таком случае Ваше определение "потокобезопасности приложения" - В СТУДИЮ!!!
Posted via ActualForum NNTP Server 1.5
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007088
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dimitry Sibiryakov

petravЕсли такое возможно, то приложение не потокобезопасно.

В таком случае Ваше определение "потокобезопасности приложения" - В СТУДИЮ!!!

Сейчас вспомню определение из документации Boost... Приложение корректно с точки
зрения многопоточности при одновременном выполнении следующих условий:

- Отсутствие гонок потоков.
- Отсутствие dead lock.
- Отсутствие priority failures.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007090
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Является 100%

Я передумал. Не 100%.

join() - это явная синхронизация, так что на выходе из потока все ок.

А вот тут место вызывающее вопросы.
Код: plaintext
1.
2.
    ++aaa;
    std::thread(doWork).join();



aaa не volatile так что технически компилятор имеет право хранить результат ++aaa в регистре в момент создания потока. Так что поток может увидеть старое значение.
На практике этого скорее всего не происходит. А может где-то даже в стандарте описано что конкретно должно происходить - лень искать.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007091
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
А так же компилятору дозволяется менять порядок вычисления всего что до join().
Так что ++ может вообще еще не произойти к моменту создания потока.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007094
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
А так же компилятору дозволяется менять порядок вычисления всего что до join().
Так что ++ может вообще еще не произойти к моменту создания потока.

Моё мнение: в данном случае компилятору предписывается выполнить всё что перед функцией создания потока.
Там у этой функции должен быть атрибут заставляющий компилятор вычислить всё что до функции создания потока.
Конечно, этот атрибут компиляторо-зависимый.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007099
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Anatoly Moskovsky
Anatoly Moskovsky
Является 100%

Я передумал. Не 100%.

Окей, спасибо. :)

Anatoly Moskovsky
join() - это явная синхронизация, так что на выходе из потока все ок.

С чего бы тут всё окей?

Anatoly Moskovsky

aaa не volatile так что технически компилятор имеет право хранить результат ++aaa в регистре в момент создания потока. Так что поток может увидеть старое значение.

Давайте всё же считать что "volatile" вообще не имеет никакого отношения к потокобезопасности.

Я предлагаю своё видение работы потока main():

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
void main()
{
    ++aaa;
    // Внутри ОС-зависимый вызов функции создания потока. Этот вызов гарантирует сброс всех регистров в кеш
    // ядра процессора. Потом гарантируется полный барьер памяти.
    std::thread(doWork).join();
    // Завершение потока гарантирует ещё один полный барьер памяти. И да, приложение потокобезопасно.
    std::cout << aaa;
}
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007102
PetroNotC Sharp
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav,
> Сейчас вспомню определение
= смешно. Ты не вспоминай. Ты ссылку дай. Взлослый же наверно.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007107
НеофитSQL
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Гость
petrav

++aaa;
std::thread(doWork).join();
std::cout << aaa;

Вопрос: является ли приложение потокобезопасным?


Я думаю что да. Хотя у вас два потока, основной останавливается на join подождать окончания второго, не производя никакой работы.
Обращение к переменной происходит в строгой очередности, что должно дать предсказуемый результат "3" при любом раскладе.

Многопроцессорная архитектура (симметричный вариант, к которому мы привыкли) проектируется таким образом, чтобы ваша программа исполнилась одинаково даже если второй поток произошел на другом ядре.

Многопоточное программирование было бы намного сложнее без таких гарантий.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007108
Фотография Anatoly Moskovsky
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Давайте всё же считать что "volatile" вообще не имеет никакого отношения к потокобезопасности.

Имеет. Но начиная с С++11 там все равно UB.

petrav Внутри ОС-зависимый вызов функции создания потока. Этот вызов гарантирует сброс всех регистров в кеш ядра процессора. Потом гарантируется полный барьер памяти.
Ну это вы описываете как должно быть по логике.
Но в стандарте с++ например то что join синхронизирует потоки описано явно, а про создание потока - нет.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007123
Dima T
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
petrav
Я прошу прощения, компилировать не буду, могу в синтаксисе ошибиться. Но суть будет понятна.

Код: plaintext
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
int aaa = 1;

void doWork()
{
    aaa++;
}

void main()
{
    ++aaa;
    std::thread(doWork).join();
    std::cout << aaa;
}


Вопрос: является ли приложение потокобезопасным?

Если внимательно посмотреть, то данный код аналогичен этому
Код: plaintext
1.
2.
3.
4.
5.
6.
void main()
{
    ++aaa;
    doWork();
    std::cout << aaa;
}


Если все так, то отрвать руки тому кто так написал. Если не так, то приводить надо адекватные примеры, а не задавать провокационные вопросы на примере кривого кода.

PS Конкретно тут сработает правильно, но так писать нельзя.
...
Рейтинг: 0 / 0
Небольшой вопрос про std::thread
    #40007128
petrav
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Dima T

Если все так, то отрвать руки тому кто так написал. Если не так, то приводить надо адекватные примеры, а не задавать провокационные вопросы на примере кривого кода.

Вопрос совершенно корректный. Код, понятно, упрощённая модель боевого кода. Пример адекватный.

Есть что сказать по теме?
...
Рейтинг: 0 / 0
25 сообщений из 82, страница 1 из 4
Форумы / C++ [игнор отключен] [закрыт для гостей] / Небольшой вопрос про std::thread
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]