передать bool по ссылке и использовать его последнее значение

У меня есть следующий код:

MyClass::aMethod()
{
...
bool isStarted = false;

boost::thread(boost::bind(&MyClass::CheckTimeoutThread, this, isStarted));

...//some time later
isStarted = true;
...
}

MyClass::checkTimeoutThread(bool &isStarted)
{
...//some code here
while(anotherFlag)
{
...//do something
if(isStarted)//ALWAYS THE INITIAL VALUE OF FALSE
{
}
...
}
}

Я ожидал isStarted переменная может быть использована как флаг, но я ошибаюсь или я что-то не так делаю.

2

Решение

boost::thread будет хранить копию своих аргументов. Но вы можете смоделировать ссылку, передав reference_wrapper с помощью boost::ref, Также обратите внимание, что вам не нужно звонить boost::bind:

boost::thread t(&MyClass::CheckTimeoutThread, this, boost::ref(isStarted));

Но обратите внимание, что теперь у вас есть условия гонки на isStarted, Вам нужно либо синхронизировать доступ к нему, скажем, с мьютексами, либо использовать атомарный тип, если он доступен на вашей платформе (если у вас есть C ++ 11, вы можете использовать std::atomic<bool>, как предложено @PeteBecker.)

редактировать Очевидно, все вышеперечисленное предполагает, что isStated живет по крайней мере до тех пор, пока thread который использует это. На практике это означает, что поток должен быть сделан ко времени aMethod возвращается. Кроме того, вы можете сделать isStarted член данных. Но вы все равно должны обязательно присоединиться к ветке до того, как MyClass деструктор уничтожает его.

3

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

Самая большая проблема (кроме std::ref или же boost::ref требуется передать ссылки на thread), что вы передаете ссылка на временный

MyClass::aMethod()
{
...
bool isStarted = false;

}

/// Oops at the end of the method, `isStarted` no longer lives

Любой доступ через устаревшая ссылка Неопределенное поведение после того, как контроль уходит aMethod

Могу ли я предложить использовать правильную синхронизацию: Посмотреть это в прямом эфире на Coliru

#include <thread>
#include <mutex>
#include <condition_variable>
#include <iostream>

struct X
{
std::condition_variable cv;
std::mutex mx;
bool isStarted;
std::thread worker;

X() : isStarted(false) {}

void aMethod()
{
worker = std::thread(&X::Worker, this);

std::this_thread::sleep_for(std::chrono::seconds(1));

{
std::cout << "signalling worker\n";
std::unique_lock<std::mutex> lock(mx);
isStarted = true;
cv.notify_one();
}

worker.join();
isStarted = false;
}

void Worker()
{
std::unique_lock<std::mutex> lock(mx);
std::cout << "worker ready\n";
cv.wait(lock, [this] { return isStarted; });
std::cout << "worker started\n";

std::cout << "worker done\n";
}
};

int main()
{
X o;
o.aMethod();
}

Обратите внимание, что

1

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