в моем коде у меня есть следующая структура:
Родительская нить
somedatatype thread1_continue, thread2_continue; // Does bool guarantee no data race?
Тема 1:
while (thread1_continue) {
// Do some work
}
Тема 2:
while (thread2_continue) {
// Do some work
}
Поэтому мне интересно, какой тип данных должен быть thread1_continue или thread2_continue, чтобы избежать гонки данных. А также, если для решения этой проблемы существует какой-либо тип данных или техника в pthread.
Нет встроенного базового типа, который гарантирует безопасность потока, независимо от того, насколько он мал. Даже если вы работаете с bool
или unsigned char
, ни чтение, ни письмо не гарантируют, что они будут атомарными. Другими словами: существует вероятность того, что если большее количество потоков будет работать независимо с одной и той же памятью, один поток может частично перезаписать эту память, в то время как другой считывает значение trash ~, в этом случае поведение не определено.
Вы можете использовать mutex
чтобы обернуть критический раздел с помощью lock
и unlock
вызовы, чтобы обеспечить взаимное исключение - будет только один поток, который сможет выполнить этот код. Для более сложной синхронизации есть семафоры, переменные условий или даже шаблоны/идиомы, описывающие, как можно обрабатывать синхронизацию с помощью этих (переключатель освещения, поворот и т.д.). Просто изучите больше об этом, некоторые простые примеры можно найти здесь :)
Обратите внимание, что могут быть некоторые более сложные типы/оболочки, которые обертывают способ обращения к объекту - например, std::atomic
template в С++ 11, который ничего не делает, кроме как внутренне обрабатывает синхронизацию для вас, t нужно сделать это явно. С std::atomic
существует гарантия, что: "если один поток записывает на атомный объект, а другой поток читает его, поведение корректно".
Для булевых (и других), избегайте
thread 1 loop
{
do actions1;
myFlag = true;
do more1;
}
thread 2 loop
{
do actions2;
if (myFlag)
{
myFlag = false;
do flagged actions;
}
do more2;
}
Это почти всегда работает до тех пор, пока myBool не будет установлен thread1, тогда как thread2 находится между проверкой и сбросом myBool. Для обработки тестовых заданий есть примитивы, зависящие от процессора, но обычное решение блокируется при доступе к общим ресурсам, даже булевым.
std::atomic<bool>
с C ++ 11.std::atomic<bool>
?