使用pthread条件变量的死锁程序,临界区[c++]



我想做的是让每个线程在main更改其他线程的结构之前使用临界区从结构体中复制信息。

#include <iostream>
#include <pthread.h>
using namespace std;
struct foo
{
public:
int var;
int *turn;
int index;
pthread_mutex_t *bsem;
pthread_cond_t *waitTurn;
};
void *threadFunc(void *arg) {
int var;
foo *workingVar = (foo *)arg;
pthread_mutex_lock(workingVar->bsem);
while (*workingVar->turn != workingVar->index)
pthread_cond_wait(workingVar->waitTurn, workingVar->bsem);
var = workingVar->var;
*workingVar->turn++;
pthread_cond_broadcast(workingVar->waitTurn);
pthread_mutex_unlock(workingVar->bsem);
cout << var << endl;
return nullptr;
}
int main() {
int turn = 0, NTHREADS = 5;
foo mainStruct;
pthread_mutex_t bsem;
pthread_mutex_init(&bsem, NULL);
pthread_cond_t waitTurn = PTHREAD_COND_INITIALIZER;
mainStruct.bsem = &bsem;
mainStruct.waitTurn = &waitTurn;
mainStruct.turn = &turn;
pthread_t tid[NTHREADS];
for (int i = 0; i < NTHREADS; i++) {
mainStruct.index = i;
mainStruct.var = i;
pthread_create(&tid[i], nullptr, threadFunc, &mainStruct);
}
for (int i = 0; i < NTHREADS; i++)
pthread_join(tid[i], NULL);
}
上面的代码来自一个线程函数。我试图让线程等待,直到使用pthread_cond_wait是他们的"turn",然后一旦条件为真,从main传递的结构信息将被复制到局部变量中,并将增加转动并退出临界区(也不使用全局变量,所以互斥锁和条件变量是使用指针通过结构体传递的)。Turn初始化为0,index是线程号(按照创建的顺序)。

此进程死锁,超时。

如果需要更多的上下文/信息,请让我知道,这是我的第一个堆栈溢出问题。

我在mainStruct.index上看到竞争条件。主线程在没有锁的情况下修改它,多个线程在锁下访问它。因此,如果第一个线程启动得很快,它将与循环生成线程交互。

看起来您计划有多个Foo实例,但是您只有一个。所以想象一下场景:

  1. 主线程到达第一个join
  2. 其他线程已创建,但尚未开始运行
  3. 在该点mainStruct.index的值为4!
  4. 第一个线程开始执行并获取锁。
  5. turn0,workingVar->index4(见第3点)
  6. 所以线程进入pthread_cond_wait并等待
  7. 下一个线程执行与第4-6点相同
  8. 所有侧线程处于等待状态

所有线程都在等待没有人调用pthread_cond_broadcast条件*workingVar->turn != workingVar->index总是true

你的代码是用C而不是C++写的。唯一的C++是使用std::cout!试着用std::thread重写这个,它会自己修复(如果你通过值传递参数)。

这是我的c++版本

相关内容

  • 没有找到相关文章

最新更新