Этот баннер — требование Роскомнадзора для исполнения 152 ФЗ.
«На сайте осуществляется обработка файлов cookie, необходимых для работы сайта, а также для анализа использования сайта и улучшения предоставляемых сервисов с использованием метрической программы Яндекс.Метрика. Продолжая использовать сайт, вы даёте согласие с использованием данных технологий».
Политика конфиденциальности
|
|
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Решил сделать свой аналог виндового Event с автосбросом на С++11 condition_variable это не совсем тоже самое что Event, т.к. Event можно сначала перевести в сигнальное состояние, позже проверить и остановки не будет. Если condition_variable.notify_one() вызвать заранее, то на wait() она уйдет в ожидание. Не совсем удобно, например, если один поток набивает очередь заданиями, а второй исполняет. Допустим в момент добавления задания второй был перед запуском ожидания заданий, то он уснет так и не выполнив задание и будет спать до следующего. Решил добавить флаг что уже будили обработчик до того как он заснул. Заодно многократное пробуждение ускорить, например, основной поток набивает очередь и многократно вызывает WakeUp() когда второй в это время разгребает эту очередь и в пробуждении не нуждается. А каждый раз обращаться к мутексу тоже не самая быстрая операция. Исходник Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. Нужен ли тут Код: plaintext 1. bool он ведь однобайтный, его невозможно частично прочитать/записать. Как понимаю достаточно написать Код: plaintext 1. что запретит компилятору хранить значение в регистрах и оно будет каждый раз читаться из памяти. Или я чего-то еще недопонимаю? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2016, 17:51 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Dima TИли я чего-то еще недопонимаю? Что использование переменных не всегда ограничивается чтением и записью. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2016, 17:57 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
У тебя в коде есть неатомарная проверка-и-сброс. Posted via ActualForum NNTP Server 1.5 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2016, 18:01 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Dimitry SibiryakovУ тебя в коде есть неатомарная проверка-и-сброс. Неатомарная проверка сводится к атомарному чтению значения и последующей проверке. возможно все это атомарно произойдет. Надо глянуть как это в асме реализовано. Опять же от компилятора зависит. Можно конечно в мутекс обернуть все изменения (мутекс уже есть), но надо ли? Я своим кодом не претендую на супернадежность, он для конкретной задачи, где ложное пробуждение не проблема, тем более что для condition_variable изначально в документации заявлена возможность ложного срабатывания, т.е. пробуждения когда не надо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 15.01.2016, 21:07 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Dima T Решил сделать свой аналог виндового Event с автосбросом на С++11 condition_variable это не совсем тоже самое что Event, т.к. Event можно сначала перевести в сигнальное состояние, позже проверить и остановки не будет. Если condition_variable.notify_one() вызвать заранее, то на wait() она уйдет в ожидание. Не совсем удобно, например, если один поток набивает очередь заданиями, а второй исполняет. Допустим в момент добавления задания второй был перед запуском ожидания заданий, то он уснет так и не выполнив задание и будет спать до следующего. Решил добавить флаг что уже будили обработчик до того как он заснул. Заодно многократное пробуждение ускорить, например, основной поток набивает очередь и многократно вызывает WakeUp() когда второй в это время разгребает эту очередь и в пробуждении не нуждается. А каждый раз обращаться к мутексу тоже не самая быстрая операция. Исходник Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. Нужен ли тут Код: plaintext 1. bool он ведь однобайтный, его невозможно частично прочитать/записать. Как понимаю достаточно написать Код: plaintext 1. что запретит компилятору хранить значение в регистрах и оно будет каждый раз читаться из памяти. Или я чего-то еще недопонимаю? В общем случае если у тебя процессор с одним ядром то можно использовать volatile. А если может быть hardware параллелизм то нужны барьеры памяти. В твоем случае class atomic и его функции-члены . ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2016, 01:44 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
YesSqlВ общем случае если у тебя процессор с одним ядром то можно использовать volatile. А если может быть hardware параллелизм то нужны барьеры памяти. В твоем случае class atomic и его функции-члены . У меня процессор любой, т.е. считаем многоядерный. Почитал инет , volatile в С заставляет хранить в памяти, но барьеры не создаются. Т.е. возможно что оптимизатор в процессоре выполнит код не в том порядке как он написан. Поэтому надо использовать atomic. Что касается присвоений, то оператор = перегружен и вызывает метод store() Над кодом долго медитировал, тут главное чтобы не случилочь так что WakeUp() вызвали, а из Wait() ожидающий не выщел. Вроде не должно быть такого. Выход из Wait() без WakeUp() не проблема: выйдет, проверит что далать нечего и обратно в Wait(). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 16.01.2016, 19:17 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Dima TНад кодом долго медитировал, тут главное чтобы не случилочь так что WakeUp() вызвали, а из Wait() ожидающий не выщел. Вроде не должно быть такого. Выход из Wait() без WakeUp() не проблема: выйдет, проверит что далать нечего и обратно в Wait(). Если два потока стоят в ожидании. И вызываем дважды WakeUp чтобы их разбудить. Между нами: Майкрософт прививает прохой вкус в паралельном программировании. ИМХО Event - совершенно бесполезный элемент. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2016, 11:13 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
YesSqlDima TНад кодом долго медитировал, тут главное чтобы не случилочь так что WakeUp() вызвали, а из Wait() ожидающий не выщел. Вроде не должно быть такого. Выход из Wait() без WakeUp() не проблема: выйдет, проверит что далать нечего и обратно в Wait(). Если два потока стоят в ожидании. И вызываем дважды WakeUp чтобы их разбудить. Верно. Но не мой случай. У меня один в ожидании. Можно под несколько ожидающих допилить, заменить на счетчик. Семафор получится. Или просто убрать проверку в WakeUp(), тогда будет два вызова cv.notify_one(), т.е. оба потока разбудит, но добавятся лишние тормоза из-за холостых cv.notify_one(). Есть мысль так поправить: делать все изменения need_wait под мутексом, на скорость не сильно повлияет. Только порешается ли проблема двойного WakeUp()? Есть одна непонятка по condition_variable: когда срабатывает выход из cv.wait(lck) ? Возможна ли какая-то пауза после вызова cv.notify_one() в другом потоке, т.е. при двух подряд WakeUp() возможно ли что первый cv.wait(lck) не начнет работу до второго вызова? Двойной WakeUp() затестю, это просто. Никак не придумаю как мой случай затестить. YesSqlМежду нами: Майкрософт прививает прохой вкус в паралельном программировании. ИМХО Event - совершенно бесполезный элемент. ИМХУ condition_variable еще более мутная конструкция. В линуксе семафоры есть. Ставим предел 1 и получается аналог виндового Event. Пока так и порешано: в линуксе семафор, в виндовсе Event. Хочу переделать универсально. Странно что в С++ 11 семафоры не перенесли. Они и в винде есть, и в линуксе. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2016, 12:36 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Dima TЕсть одна непонятка по condition_variable: когда срабатывает выход из cv.wait(lck) ? Возможна ли какая-то пауза после вызова cv.notify_one() в другом потоке, т.е. при двух подряд WakeUp() возможно ли что первый cv.wait(lck) не начнет работу до второго вызова? Хмм.. Не совсем понятно. Твой lck будет захвачен выходящим из wait потоком и пока он не освободится другой поток не выйдет из wait. И notify тоже будет заблокирована. Dima TДвойной WakeUp() затестю, это просто. достаточно сделать notify_all() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 18.01.2016, 20:58 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
YesSqlDima TЕсть одна непонятка по condition_variable: когда срабатывает выход из cv.wait(lck) ? Возможна ли какая-то пауза после вызова cv.notify_one() в другом потоке, т.е. при двух подряд WakeUp() возможно ли что первый cv.wait(lck) не начнет работу до второго вызова? Хмм.. Не совсем понятно. Твой lck будет захвачен выходящим из wait потоком и пока он не освободится другой поток не выйдет из wait. Я о том что notify_one() никак с мутексом не связан и теоретически может быть вызван дважды до выхода из cv.wait(lck) Т.е. нормально если так отработает: Поток1Поток2need_wait = falsecv.notify_one()выход из cv.wait(lck)need_wait = trueneed_wait = falsecv.notify_one()выход из cv.wait(lck)need_wait = true ненормально если так Поток1Поток2need_wait = falsecv.notify_one()need_wait = false cv.notify_one() выход из cv.wait(lck)need_wait = true тут красный notify_one() не сработает, т.к. у теня он вызывается только при need_wait == true. Т.е. будет одно пробуждение на два WakeUp() ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2016, 18:16 |
|
||
|
std::atomic<bool> или volatile bool ? Есть разница?
|
|||
|---|---|---|---|
|
#18+
Версия 1.1 Код: plaintext 1. 2. 3. 4. 5. 6. 7. 8. 9. 10. 11. 12. 13. 14. 15. 16. 17. 18. 19. 20. 21. 22. 23. 24. 25. 26. 27. 28. 29. 30. 31. 32. 33. 34. 35. 36. 37. 38. 39. 40. 41. 42. 43. 44. 45. 46. 47. 48. 49. 50. 51. 52. 53. 54. 55. 56. 57. 58. 59. 60. 61. 62. 63. 64. 65. 66. 67. 68. 69. 70. 71. 72. 73. 74. 75. 76. 77. 78. 79. 80. 81. Немного допилил, по-максимуму все под мутекс убрал. Несмотря на мои сомнения несколько WakeUp() подряд нормально отрабатывает. В коде ниже тест так построен что если один WakeUp() не сработает, то все повиснет в мертвой блокировке. Ни разу не повисло ни на одном ядре, ни на 4-х. PS Тут 18706927 книгу упомянули, там как раз целая глава по моей теме. Расписано почему надо использовать atomic. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 21.01.2016, 18:19 |
|
||
|
|

start [/forum/topic.php?fid=57&fpage=38&tid=2018634]: |
0ms |
get settings: |
10ms |
get forum list: |
13ms |
check forum access: |
4ms |
check topic access: |
4ms |
track hit: |
79ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
92ms |
get tp. blocked users: |
1ms |
| others: | 13ms |
| total: | 230ms |

| 0 / 0 |
