[英]Mutual exclusions, How to implement try_lock() method using Lamport's Bakery Algorithm?
[英]Implementation of Lamport's Bakery Algorithm has seg faults with more than 1 thread
我正在使用pthreads和Processor類來實現Lamport的Bakery算法,以充當共享內存。 使用單個線程,它可以正常工作,使用2個線程,在線程2經過30次嘗試訪問“面包房”的所有嘗試后,我遇到了seg錯誤:
dl-tls.c:沒有這樣的文件或目錄。
使用3個或更多線程時,從akerysterAlgo函數兩次輸出“ here”后,出現段錯誤:
Processor.cpp:33上Processor :: getNumber(this = 0x5b18c483)中的0x0804ae52
面包店
struct argStruct {
vector<Processor>* processors;
Processor* processor;
};
int findMax(vector<Processor>* processors) {
int max = -99;
for (int i = 0; i < processors->size(); i++) {
if (processors->at(i).getNumber() > max) {
max = processors->at(i).getNumber();
}
}
return max;
}
void* bakeryAlgo(void* arg) {
struct argStruct* args = static_cast<struct argStruct *>(arg);
cout << "here" << endl;
for (int i = 0; i < 30; i++) {
args->processor->setChoosing(1);
args->processor->setNumber(findMax(args->processors));
args->processor->setChoosing(0);
for (int j = 0; j < args->processors->size(); j++) {
int jChoosing = args->processors->at(j).getChoosing();
int jNumber = args->processors->at(j).getNumber();
int jId = args->processors->at(j).getId();
int pNumber = args->processor->getNumber();
int pId = args->processor->getId();
if (jId != pId) {
while (jChoosing != 0) {}
while (jNumber != 0 && ((jNumber < pNumber) || ((jNumber == pNumber) && (jId < pId)))) { }
}
}
cout << "Processor: " << args->processor->getId() << " executing critical section!" << endl;
args->processor->setNumber(0);
}
}
int main(int argc, char *argv[]) {
// Check that a command line argument was provided
if (2 == argc) {
int numProcessors = atoi(argv[1]);
vector<Processor> processors;
vector<argStruct> argVect;
vector < pthread_t > threads;
for (int i = 0; i < numProcessors; i++) {
Processor p = Processor(i);
processors.push_back(p);
}
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
for (int i = 0; i < numProcessors; i++) {
pthread_join(threads.at(i), NULL);
}
}
else {
cout << "Usage: bakery num, num is number of threads." << endl;
}
return 0;
}
Processor.cpp / Processor.h中的代碼很簡單,它只是關於值id,選擇和數字的一些獲取器和設置器,具有默認構造函數和采用int id的構造函數。
Processor::Processor() {
}
Processor::Processor(int idval) {
id = idval;
choosing = 0;
number = 0;
}
Processor::~Processor() {
}
int Processor::getChoosing() {
return choosing;
}
int Processor::getNumber() {
return number;
}
int Processor::getId() {
return id;
}
void Processor::setChoosing(int c) {
choosing = c;
}
void Processor::setNumber(int n) {
number = n;
}
有誰知道為什么發生這些段錯誤? gdb表示發生的位置對我而言似乎是無辜的代碼行。
您是否正在使用指向main
定義的vector
的指針作為數據? 堆棧未在線程之間共享,因此訪問該內存的其他線程充其量是未定義的行為。 我希望這是您麻煩的根源。
您正在改變的向量中獲取元素的地址:
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
// danger!
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
每次將新線程推入threads vector
,該向量都可能會在內存中重新定位,因此當添加下一個線程時,傳遞給pthread_create的指針可能指向垃圾。
您要改為執行此操作:
for (int i = 0; i < numProcessors; i++) {
pthread_t processorThread;
struct argStruct args;
args.processors = &processors;
args.processor = &processors.at(i);
argVect.push_back(args);
threads.push_back(processorThread);
}
for (int i = 0; i < numProcessors; i++) {
pthread_create(&threads.at(i), NULL, &bakeryAlgo, &argVect.at(i));
}
通過在創建線程之前等待所有元素都添加到向量中,現在可以傳遞在線程運行時保持良好狀態的指針。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.