У меня возникли некоторые проблемы с программой, использующей pthreads, где происходят случайные сбои, которые могут быть связаны с тем, как потоки работают с данными
Поэтому у меня есть несколько основных вопросов о том, как программировать с использованием потоков,и расположение памяти:
Предположим, что функция открытого класса выполняет некоторые операции над некоторыми строками и возвращает результат в виде строки.Прототип функции может выглядеть следующим образом:
std::string SomeClass::somefunc(const std::string &strOne, const std::string &strTwo)
{
//Error checking of strings have been omitted
std::string result = strOne.substr(0,5) + strTwo.substr(0,5);
return result;
}
- Правильно ли предположить, что строки, будучи динамическими, хранятся в куче, но ссылка на строку размещается встек во время выполнения?
Стек: адрес указателя [Some mem addr], на котором находится строка в куче
Heap: память [Some mem addr], выделенная дляисходная строка, которая может увеличиваться или уменьшаться
Чтобы сделать поток функции безопасным, функция расширяется следующим мьютексом (который объявлен как закрытый в блокировке SomeClass):
std::string SomeClass::somefunc(const std::string &strOne, const std::string &strTwo)
{
pthread_mutex_lock(&someclasslock);
//Error checking of strings have been omitted
std::string result = strOne.substr(0,5) + strTwo.substr(0,5);
pthread_mutex_unlock(&someclasslock);
return result;
}
Является ли это безопасным способом блокировки операций, выполняемых над строками (все три), или может ли планировщик остановить поток в следующих случаях, которые, как я предполагаю, могут испортить предполагаемыйлогика:
а.Сразу после вызова функции и установки параметров: strOne & strTwo в двух ссылочных указателях, которые функция имеет в стеке, планировщик отнимает время обработки для потока и пропускает новый поток, который перезаписывает ссылкууказатели на функцию, которая затем снова останавливается планировщиком, позволяя первому потоку вернуться обратно?
b.Может произойти то же самое со строкой «result»: первая строка создает результат, разблокирует мьютекс, но перед возвратом планировщик запускает другой поток, который выполняет всю свою работу, перезаписывая результат и т. Д.
Или опорные параметры / строка результата помещаются в стек, пока другой поток выполняет свою задачу?
Это безопасный / правильный способ сделать это в потоках и «вернуть» результат, чтобы передать ссылку на строку, которая вместо этого будет заполнена результатом:
void SomeClass:: somefunc (const std :: string & strOne, const std :: string & strTwo, std :: string result) {pthread_mutex_lock (& someclasslock);
// Проверка ошибок строк была опущена result = strOne.substr (0,5) + strTwo.substr (0,5);
pthread_mutex_unlock (& someclasslock);}
Предполагаемая логика заключается в том, что несколько объектов класса SomeClass создают новые потоки и передают сами объекты в качестве параметров, а затем вызывают функцию: "someFunc":
int SomeClass::startNewThread()
{
pthread_attr_t attr;
pthread_t pThreadID;
if(pthread_attr_init(&attr) != 0)
return -1;
if(pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED) != 0)
return -2;
if(pthread_create(&pThreadID, &attr, proxyThreadFunc, this) != 0)
return -3;
if(pthread_attr_destroy(&attr) != 0)
return -4;
return 0;
}
void* proxyThreadFunc(void* someClassObjPtr)
{
return static_cast<SomeClass*> (someClassObjPtr)->somefunc("long string","long string");
}
Извините за длинное описание.Но я надеюсь, что вопросы и предполагаемая цель ясны, если не сообщите мне, и я уточню.
С наилучшими пожеланиями.Chris