Будет ли это невмешательство в многопоточную среду?

std::deque<T> dq;
Thread_function(pointer to queue as argument)     // created 8 threads
{
vertext_found = true;
**v is initialized to NULL
while ( i < dq->size())
{
EnterCriticalSection(&h);
if( i < dq.size() ) {
v = dq.at(i);      // accessing element of queue without popping
i++;
vertext_found = true;
}
LeaveCriticalSection(&h);
if (vertext_found && (i < dq.size()) && v != NULL)
{
**operation on 'v'
vertext_found = false;
}
}
}

Будет ли это условие гонки данных, особенно при обработке?в то время как я < dq-> размер ())«за пределами критического раздела? Мой подход правильный? В противном случае, пожалуйста, предложите мне.

-1

Решение

Будет ли это невмешательство в многопоточную среду?

В тексте вашего вопроса, dq (как и все другие переменные в вашей функции) является местный объект:

std::deque<T> dq;

Если это действительно так, то на вопрос есть простой ответ: «Да». Это потокобезопасно, потому что нет конфликта: каждый поток работает на локальном объекте, и поскольку нет общего доступа, не может быть никакой гонки данных.


Теперь предположим, что ваш код предназначен для демонстрации использования общий структура данных, и это dq на самом деле глобальный объект или что-то как-то доступно одновременно нескольким потокам (это то, что dq->size() вызов функции, кажется, предлагает), тогда ответ «Это зависит».

Если все ваши потоки одновременно выполняют только ту функцию, которую вы показываете, и dq ссылка или указатель на const, так что ваша функция не содержит никакого вызоваconst функции-члены, то ответ «Да, но тебе не нужно любой критическая секция вообще в этом случае «. Пункт 17. 6.5.9 / 3 Стандарта C ++ 11 определяет:

Стандартная библиотечная функция C ++ не должна прямо или косвенно изменять объекты (1.10), доступные для потоков
кроме текущего потока, если к объектам не обращаются напрямую или косвенно через функциюconst
аргументы, в том числе this,

Ссылка на пункт 1.10 (и, в частности, на 1.10 / 21), который определяет, что такое гонки данных, проясняет значение вышеприведенного абзаца:

Выполнение программы содержит гонку данных, если она содержит два конфликтующие действия в разных темах,
по крайней мере, один из которых не является атомарным, и ни один не происходит раньше другого. Любая такая гонка данных приводит к
неопределенное поведение. […]

Наконец, пункт 1.10 / 4 определяет, когда два действия конфликтуют:

Две оценки выражений конфликтуют, если одна из них изменяет ячейку памяти (1.7), а другая —
осуществляет доступ или изменяет одну и ту же ячейку памяти.

Из всего этого следует, что const функции-члены обязательно потокобезопасны. Вы можете быть заинтересованы в просмотре эта презентация Херб Саттер об этом.

поскольку deque<T>::size() это const функция-член и at() это const функция-член (потому что вы вызываете ее из ссылки или указателя на const) который возвращает ссылку на const, нет необходимости синхронизировать доступ из нескольких потоков.


Если твой dq является не ссылка или указатель на const, тогда ответ «нет«, так как at() это неconst функция-член. Более того, так как v неконстантная ссылка на элемент, ваша «операция над v«может быть неconstпоэтому вводя гонку данных на элементы из dq а не на dq сам.

Так же, если ваши потоки одновременно обращаются и изменяют dq через другие функции, тогда ответ снова «Нет», потому что вы не защищаете все доступы к общему объекту. Операции чтения конфликтуют с операциями записи (см. Выше), и вы защищаете только немного из них. В этом случае ваш критический раздел должен охватывать весь while цикл.

4

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]