Есть ли способ использовать функцию-член класса для запуска в параллельном потоке без передачи * this в С++ 11?

Я новичок в многопоточности С++ 11 и пытаюсь использовать функцию-член класса для запуска в параллельных потоках.

В ответ на мой предыдущий вопрос я получил предложение:

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);

Я реализовал вышеуказанное предложение. Он устранил ошибку компиляции, которая у меня была, но ввел ошибку времени выполнения. В другом вопросе я получил предложение удалить весь механизм копирования. На самом деле я не хочу копировать данные, потому что код предназначен для анализа методом конечных элементов и требует много памяти.

Есть ли способ сделать это?

Заголовок аналогичен следующему.

SomeClass {
    vector<int*> someVariable;
public:
    ~SomeClass();
    void threadedMethod(bool, bool); // Inside this method the 
                                     // member vector 'someVariable' is used.

    void someMethod();               // In this function the threadedMethod has
                                     // been used twice to make 2 different thread
};

Реализация someMethod такова:

void SomeClass::someMethod() {
    thread t1(&SomeClass::threadedMethod, *this, arg1, arg2);
    thread t2(&SomeClass::threadedMethod, *this, arg1, arg2);
    t2.join();
    t1.join();
}

Деструктор подобен следующему,

SomeClass::~SomeClass() {
    int count  = someVariable.size();
    for(int i=0; i < count; i++) {
        delete someVariable[i];
    }
}

ThreadMethod обращается к переменной. Операции параллельны данным. В результате ни один поток не будет писать в один и тот же блок памяти. Опять же, память чтения и записи отличается. Там, я думаю, мне не нужны никакие замки.

Как видите, я использую *this, и это вызывает много копий. Мне действительно нужно избегать этого. Может ли кто-нибудь предложить какой-либо другой способ, который позволит мне избежать копирования?

Если вам нужно больше объяснений, пожалуйста, дайте мне знать. Если в моих силах, я постараюсь уточнить как можно больше.

Я использую Intel Mac с OS X 10.8.3. Я кодирую Xcode 4.6.1. Компилятор Apple LLVM 4.2 (компилятор по умолчанию).


person Raiyan Kabir    schedule 01.04.2013    source источник
comment
Вы пробовали просто передать this (вместо *this)?   -  person Andy Prowl    schedule 01.04.2013
comment
@AndyProwl, не могли бы вы поместить это в раздел ответов? Это работает как по волшебству. Большое спасибо. Вы спасли мой день (ну, ночь :p).   -  person Raiyan Kabir    schedule 01.04.2013
comment
Я отправил ответ :) Это решает вашу проблему?   -  person Andy Prowl    schedule 01.04.2013
comment
@ЭндиПроул. Да. Большое спасибо, приятель.   -  person Raiyan Kabir    schedule 01.04.2013
comment
Пожалуйста, рад, что помогло!   -  person Andy Prowl    schedule 01.04.2013


Ответы (1)


Аргументы передаются по значению конструктору std::thread. Следовательно, это утверждение:

std::thread t1(&SomeClass::threadFunction, *this, arg1, arg2);
//                                         ^^^^^

Запускает копию *this, а это не то, что вам нужно. Однако std::thread также может принимать указатель на объект, для которого должна быть вызвана функция-член, точно так же, как std::bind.

Следовательно, при передаче this (вместо *this) в качестве аргумента именно указатель — вместо заостренного объекта — будет передан по значению и в конечном итоге скопирован. Это не вызовет создания копирования SomeClass, как вы хотите.

Таким образом, вы должны переписать приведенное выше утверждение следующим образом:

std::thread t1(&SomeClass::threadFunction, this, arg1, arg2);
//                                         ^^^^
person Andy Prowl    schedule 01.04.2013