Предотвращение гонки данных булевых переменных с помощью pthreads

0

в моем коде у меня есть следующая структура:

Родительская нить

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.

  • 0
    std::atomic<bool> с C ++ 11.
  • 1
    Как насчет std::atomic<bool> ?
Теги:
multithreading
parallel-processing
synchronization
pthreads

2 ответа

2

Нет встроенного базового типа, который гарантирует безопасность потока, независимо от того, насколько он мал. Даже если вы работаете с bool или unsigned char, ни чтение, ни письмо не гарантируют, что они будут атомарными. Другими словами: существует вероятность того, что если большее количество потоков будет работать независимо с одной и той же памятью, один поток может частично перезаписать эту память, в то время как другой считывает значение trash ~, в этом случае поведение не определено.

Вы можете использовать mutex чтобы обернуть критический раздел с помощью lock и unlock вызовы, чтобы обеспечить взаимное исключение - будет только один поток, который сможет выполнить этот код. Для более сложной синхронизации есть семафоры, переменные условий или даже шаблоны/идиомы, описывающие, как можно обрабатывать синхронизацию с помощью этих (переключатель освещения, поворот и т.д.). Просто изучите больше об этом, некоторые простые примеры можно найти здесь :)

Обратите внимание, что могут быть некоторые более сложные типы/оболочки, которые обертывают способ обращения к объекту - например, std::atomic template в С++ 11, который ничего не делает, кроме как внутренне обрабатывает синхронизацию для вас, t нужно сделать это явно. С std::atomic существует гарантия, что: "если один поток записывает на атомный объект, а другой поток читает его, поведение корректно".

0

Для булевых (и других), избегайте

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. Для обработки тестовых заданий есть примитивы, зависящие от процессора, но обычное решение блокируется при доступе к общим ресурсам, даже булевым.

Ещё вопросы

Сообщество Overcoder
Наверх
Меню