|
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
|
||||||
Один mutex на несколько функций19.04.2016, 13:56. Показов 6922. Ответов 50
Метки нет (Все метки)
Есть три функции, которые могут работать с одним вектором в одно и то же время из разных потоков. Можно ли использовать один мьютекс на эти несколько функций, чтобы не синхронизировать работу 3-х мьютексов?
Код чисто для примера, чтобы было понятно, чего я хочу
2
|
||||||
| 19.04.2016, 13:56 | |
|
Ответы с готовыми решениями:
50
вывод на один график несколько функций
Несколько функций в IF |
|
2549 / 1208 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
|
|
| 20.04.2016, 11:41 | |
|
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
||
| 20.04.2016, 13:07 | ||
|
Если несколько потоков используют мьютекс для доступа к ресурсу, при этом порядок обращения к мьютексу и время удержания произвольные, то где гарантия, что один и тот же поток не будет неограниченно долго удерживать мьютекс просто освобождая и тут же захватывая его повторно, ведь очереди нет, и не гарантируется, что освобождение мьютекса одним поток обязательно активирует ожидающих?
0
|
||
|
22 / 22 / 10
Регистрация: 19.03.2015
Сообщений: 137
|
||
| 20.04.2016, 13:38 [ТС] | ||
|
0
|
||
|
Вездепух
13205 / 6840 / 1822
Регистрация: 18.10.2014
Сообщений: 17,298
|
||||
| 20.04.2016, 20:32 | ||||
|
Race condition ("гонка") - это огромный класс семантических проблем, суть которых сводится к тому, что программа пытается завязываться на такие предположения о многопоточном поведении, которые на самом деле является неопределенными (unspecified или undefined). А именно, когда программа пытается делать предположения о существовании некоего детерминированного "порядка" или "скорости" выполнения потоков. В этом множестве вариантов разнообразных гонок несинхронизированный/неатомарный доступ к кусочку данных - это лишь очень узенький и весьма нерепрезентативный частный пример возможной гонки. Это во-первых. Во-вторых, предположение о том, что "заоболачивание" доступа к данным в mutex как-то решает проблему гонки - наивное заблуждение. Это не говоря уже о том, что приемы синхронизации в многопоточном программировании далеко не сводятся к использованию "классических" примитивов, типа mutex. Вот вам искусственный пример гонки, причем буквальной: пусть у меня есть глобальная переменная int i = 0 и несколько одинаковых потоков, которые, кроме прочего, делают ++i и запоминают результат. Пусть я запускаю эти потоки поочередно с задержкой Dt по времени между потоками. И я предполагаю, что те потоки, которые стартовали раньше, "доберутся" до ++i тоже раньше. Соответственно, я предполагаю, что первый запущенный поток получит из i значение - 1, второй - 2 и т.д. Пусть я в дальнейшем коде сильно завишу от выполнения этого предположения.Вот это - яркий пример гонки. Мое предположение - грубейшим образом некорректно. То, что некий поток стартовал позже, никак не мешает ему обогнать более ранний поток в процессе выполнения. При этом заоболачивание доступа к ++i в mutex никак делу не поможет - выполнение моего предположения все равно не гарантируется и оно не будет выполняться. Вот это - классический race condition. Заоболочив доступ к ++i в mutex я лишь перенес точку финиша в этой гонке, но саму гонку и ее негативные последствия никак не устранил.Нерадивый программист в такой ситуации может начать увеличивать величину задержки Dt, в надежде на то, что для какого-то значения Dt порядок прихода потоков на ++i, наконец, станет совпадать с порядком их запуска. Понятно, что это не более чем профанация.В такой ситуации, если я действительно хочу, чтобы потоки выполняли ++i в некотором четко определенном мною порядке, я должен буду самостоятельно насильно ловить и задерживать "выбившиеся вперед" потоки. И делать это придется вручную.Такая гарантия есть, потому что освобождение и последующий захват одного mutex потоком A - операция неатомарная. В традиционной реализации, если в этот момент какой-то другой поток B ожидал этого же mutex и был в этот момент готов к выполнению, этот поток B тут же захватит этот mutex еще в момент освобождения его потоком A. Как бы быстро A не попытался снова захватить mutex, он все равно "не успеет". Такой гарантии нет например потому, что ожидающий поток B в момент освобождения mutex может оказаться не готов к выполнению. Например, ОС могла "на секундочку" захватить ресурсы потока B и переиспользовать их для решения каких-то своих внутренних задач (типа обслуживания прерывания неким внутренним системным потоком C). Поток B на это время будет "заморожен". Т.е. может получится так, что поток B "прохлопает" свою возможность захватить mutex, и поток A сможет успеть снова захватить его прямо под носом у потока B. Но это - вопросы реализации грамотного управления потоками на уровне внутренностей ОС. Это задача ОС, обеспечить базовые гарантии, вроде тех, что потоки одинакового приоритета не будут как-то выражено дискриминироваться планировщиком потоков. Но опять же, в недискриминирующем отношении ОС к потокам не содержится никаких гарантий порядка выполнения потоков. Если вам нужен порядок - огранизуйте его сами. И многопоточное программирование предполагает дизайн программы по принципу: если что-то очень маловероятно, но теоретически возможно, то оно рано или поздно произойдет. Добавлено через 10 минут Когда некто в форуме "для начинающих математиков" задает вопрос типа "Решал уравнение x + 2 = 4. Получил ответ x=3, но что-то не сходится. Где ошибка?", то на такой вопрос можно дать два принципиально разных ответа. Первый ответ: "Правильное решение x=2. Свободен.". Второй ответ: "Покажи, как ты получил такой странный результат (а мы покажем тебе, где именно ты ошибся в процессе решения)". Я лично считаю, что в такой "странной" ситуации, как "решал x + 2 = 4, получил x=3" первый вариант ответа на самом деле бесполезен, а осмысленен именно и только второй вариант ответа. Вот так же и здесь, когда я у вас спрашиваю, "откуда возник такой вопрос", цель этого - именно понять, какая цепочка умозаключений привела вас к "странному" выводу, что для трех функций необходимо три мьютекса, и затем уже искать ошибку в этой цепочке. Ни больше, ни меньше.
5
|
||||
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|||
| 20.04.2016, 23:14 | |||
|
0
|
|||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 20.04.2016, 23:32 | |
|
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
||
| 21.04.2016, 10:38 | ||
|
0
|
||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||
| 21.04.2016, 11:48 | ||
|
0
|
||
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|
| 21.04.2016, 11:55 | |
|
avgoor, дело не в том, что останавливает планировщик, а в том по чьей команде.
0
|
|
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
||
| 21.04.2016, 12:01 | ||
|
А вообще, планировщик делают с оглядкой на такие вещи.
1
|
||
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
||
| 21.04.2016, 14:31 | ||
|
0
|
||
|
27 / 26 / 6
Регистрация: 02.02.2014
Сообщений: 96
|
|
| 21.04.2016, 15:06 | |
|
Логично потратить как можно меньше времени и разбудить первый попавшийся ждущий поток. Fair синхронизация нужна слишком редко, чтобы ради нее в ядро вкорячивать лишний код, тем более в таком месте.
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
||
| 21.04.2016, 15:14 | ||
|
0
|
||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|||
| 21.04.2016, 17:06 | |||
|
0
|
|||
|
27 / 26 / 6
Регистрация: 02.02.2014
Сообщений: 96
|
|
| 21.04.2016, 17:17 | |
|
Пример: поток освобождает мьютекс (лежащий за ним футекс) и будит ожидающего. Но в этот момент набегает новый поток и хватает освободившийся футекс. Проснувшийся ожидавший видит, что прощелкал свой шанс и засыпает обратно, причем уже в конце очереди. И вот такое проверять никто не будет без нужды.
0
|
|
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|
| 21.04.2016, 17:17 | |
|
Поясню подробнее. Один поток может 10 раз успеть захватить и освободить мьютекс, пока второй доберется до захвата этого мьютекса, т.е. постановки в очередь.
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
|||
| 21.04.2016, 18:04 | |||
|
0
|
|||
|
1550 / 877 / 179
Регистрация: 05.12.2015
Сообщений: 2,555
|
|||
| 21.04.2016, 18:23 | |||
|
2) Если потоки равнозначны (читай делают одно и то же) - какая вам разница, какой поток захватит мьютекс? 3) Если потоки не равнозначны - какая разница, какой из них первым попытался захатить мьютекс, если все равно нужен приоритет? Исходя из вышесказанного зачем нужна строгая очередность в захвате мьютексов? Добавлено через 8 минут
0
|
|||
|
27 / 26 / 6
Регистрация: 02.02.2014
Сообщений: 96
|
|
| 21.04.2016, 18:27 | |
|
О какой именно "равномерности" речь?
0
|
|
|
7804 / 6568 / 2988
Регистрация: 14.04.2014
Сообщений: 28,705
|
||||
| 21.04.2016, 18:50 | ||||
|
Добавлено через 2 минуты
0
|
||||
| 21.04.2016, 18:50 | |
|
Помогаю со студенческими работами здесь
40
несколько функций Реализовать несколько функций Добавить несколько функций Несколько функций поток Несколько примеров функций Искать еще темы с ответами Или воспользуйтесь поиском по форуму: |
|
Новые блоги и статьи
|
|||
|
[golang] Алгоритм «Хак Госпера»
alhaos 17.05.2026
Алгоритм «Хак Госпера»
Хак Госпера (Gosper's Hack) — алгоритм нахождения следующего по величине числа с тем же количеством установленных бит.
Придуман Биллом Госпером в 1970-х, опубликован в. . .
|
Рисование бинарного древа до 6-го колена на js, svg.
russiannick 17.05.2026
<svg width="335" height="240" viewBox="0 0 335 240" fill="#e5e1bb">
<style>
<!]>
</ style>
<g id="bush">
</ g>
</ svg>
function fn(){
let rost;/ / высота древа
let xx=165,yy=210,w=256;
|
FSharp: interface of module
DevAlt 16.05.2026
Интерфейс модуля F# позволяет управлять доступностью членов,
содержащихся в реализации модуля. По-умолчанию все члены модуля доступны:
module Foo
let x = 10
let boo () = printfn "boo"
. . .
|
Хитросплетение родственных связей пантеона греческих богов.
russiannick 14.05.2026
Однооконник, позволяющий узреть и изучить отдельных героев древней Греции.
<!DOCTYPE html>
<html lang="ru">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible". . .
|
|
[golang] Угол между стрелками часов
alhaos 12.05.2026
По заданным значениям часа и минуты необходимо определить значение меньшего угла между стрелками аналогового циферблата часов.
import "math"
func angleClock(hour int, minutes int) float64 {
. . .
|
Debian 13: Установка Lazarus QT5
ВитГо 09.05.2026
Эта инструкция моя компиляция инструкций volvo
https:/ / www. cyberforum. ru/ blogs/ 203668/ 10753. html
и его же старой инструкции по установке Lazarus с gtk2. . .
|
Нейросеть на алгоритме "эстафета хвоста" как перспектива.
Hrethgir 06.05.2026
На десерт, когда запущу сервер.
Статья тут https:/ / habr. com/ ru/ articles/ 1030914/ . Автор я сам, нейросеть только помогает в вопросах которые мне не известны - не знаю людей которые знали-бы. . .
|
Асинхронный приём данных из COM-порта
Argus19 01.05.2026
Асинхронный приём данных из COM-порта
Купил на aliexpress термопринтер QR701. Он оказался странным. Поключил к Arduino Nano. Был очень удивлён. Наотрез отказывается печатать русские буквы. Чтобы. . .
|