[英]How to safely operate on parameters in threads, using C++ & Pthreads?
我在使用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]指向字符串在堆上的位置的指針地址
堆:[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,調度程序占用了線程的處理時間,並允許一個新線程進入,該線程覆蓋了引用指向函數的指針,然后該指針又被調度程序停止,讓第一個線程返回?
灣 “結果”字符串會發生同樣的情況:第一個字符串生成結果,解鎖互斥鎖,但是在返回調度程序之前,讓另一個線程執行所有工作,覆蓋結果等。
還是在另一個線程執行任務時將參考參數/結果字符串壓入堆棧?
是在線程中執行此操作並“返回”結果的安全/正確方法,以將引用傳遞給將由結果填充的字符串:
無效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");
}
很抱歉,冗長的描述。 但我希望問題和意圖明確,如果不能讓我知道,我會詳細說明。
最好的祝福。 克里斯
1 a / b:否,都不會發生。 函數的參數及其返回值位於堆棧上,每個線程都有自己的堆棧。 但是,其他事情肯定會出錯:
我建議您為每個線程創建一個新的SomeClass對象。 在那種情況下,這些對象的所有成員只能由一個線程訪問,而不必由鎖保護。 缺點是,啟動新線程后,您將無法再從主線程訪問它們。 如果那是必需的,那么您必須使用鎖來保護它們(該鎖也將是該類的成員)。
話雖如此,函數somefunc似乎根本不影響對象的任何成員,因此不需要保護。 考慮一下線程之間共享的粒度,在我看來,保護鎖應該在調用somefunc的函數中。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.