用ubuntu虚拟机写qt,在MainWindow类中写的好几个相关死锁代码总是异常中断,但把这部分代码单独提出写在一个cpp中就能编译通过并且正常输出
类里死锁代码部分
(简化了一下,只粘了最基本的一个死锁多线程)
//mainwindow.h
namespace Ui {
class MainWindow;
}
class MainWindow : public QMainWindow
{
Q_OBJECT
public:
explicit MainWindow(QWidget *parent = 0, Qt::WindowFlags flags = 0);
~MainWindow();
private:
Ui::MainWindow *ui;
static void* Q2(void *arg);
static void* P2(void *arg);
void InitializedTable_unlock();
void choose(int);
public slots:
void unlock();
};
#endif // MAINWINDOW_H
//mainwindow.cpp
pthread_t tid[2];
// 静态初始化互斥量
pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER;
MainWindow::MainWindow(QWidget *parent, Qt::WindowFlags flags) :
QMainWindow(parent),
ui(new Ui::MainWindow)
{
ui->setupUi(this);
connect(ui->pushButton_3_1_b,SIGNAL(clicked()),this,SLOT(unlock()));
}
MainWindow::~MainWindow()
{
delete ui;
}
void* MainWindow::P1(void *arg) {
MainWindow w;
pthread_mutex_lock(&mutexA);
//P1 get mutexA
//choose按钮对应移动函数
w.choose(1);
usleep(1000);
pthread_mutex_lock(&mutexB);
//P1 get mutexB
w.choose(3);
pthread_mutex_unlock(&mutexA);
//P1 release mutexB
w.choose(4);
pthread_mutex_unlock(&mutexB);
//P1 release mutexA
w.choose(5);
return NULL;
}
void* MainWindow::Q1(void *arg) {
MainWindow w;
pthread_mutex_lock(&mutexB);
//Q1 get mutexB
w.choose(2);
usleep(1000);
pthread_mutex_lock(&mutexA);
//Q1 get mutexA
w.choose(6);
pthread_mutex_unlock(&mutexB);
//Q1 release mutexA
w.choose(7);
pthread_mutex_unlock(&mutexA);
//Q1 release mutexB
w.choose(8);
return NULL;
}
void MainWindow::lock(void) {
MainWindow m;
// 创建线程 1
pthread_create(&(tid[0]), NULL, m.Q1, NULL );
// 创建线程 2
pthread_create(&(tid[1]), NULL, m.P1, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
}
// 死锁资源按钮相应位移函数
void MainWindow::choose(int step){
if(step == 1){
//P1 get mutexA
......全都写的是对应的button进行位移的代码
}
else if(step == 2){
//Q1 get mutexB
......
}
else if(step == 3){
//P2 release mutexA
......
}
else if(step == 4){
//P2 get mutexB
......
}
else if(step == 5){
//P2 release mutexB
......
}
else if(step == 6){
//Q2 get mutexA
......
}
else if(step == 7){
//Q2 release mutexB
......
}
else if(step == 8){
//Q2 release mutexA
QPropertyAnimation *animation12 = new
QPropertyAnimation(ui->pushButton_2_1_1,"geometry");
animation12->setDuration(1000);
animation12->setStartValue(QRect(110,280,141,71));
animation12->setEndValue(QRect(110,140,141,71));
animation12->start();
QPropertyAnimation *animation13 = new
QPropertyAnimation(ui->pushButton_2_1_1,"geometry");
animation13->setDuration(1000);
animation13->setStartValue(QRect(110,140,141,71));
animation13->setEndValue(QRect(530,140,141,71));
animation13->start();
}
}
这部分代码运行不出来,不报错,但click一下那个unlock就异常中断
然后我把这部分代码单独整理成一个cpp就能跑
#include <QCoreApplication>
#include<pthread.h>
#include<semaphore.h>
#include<unistd.h> //用于sleep()
pthread_t tid[2];
// 静态初始化互斥量
pthread_mutex_t mutexA = PTHREAD_MUTEX_INITIALIZER;
pthread_mutex_t mutexB = PTHREAD_MUTEX_INITIALIZER;
void* P1(void *arg) {
pthread_mutex_lock(&mutexA);
printf("P1 get mutexA\n");
usleep(1000);
pthread_mutex_unlock(&mutexB);
printf("P1 release mutexA\n");
pthread_mutex_lock(&mutexB);
printf("P1 get mutexB\n");
pthread_mutex_unlock(&mutexA);
printf("P1 release mutexB\n");
return NULL;
}
void* Q1(void *arg) {
pthread_mutex_lock(&mutexB);
printf("Q1 get mutexB\n");
usleep(1000);
pthread_mutex_lock(&mutexA);
printf("Q1 get mutexA\n");
pthread_mutex_unlock(&mutexB);
printf("Q1 release mutexA\n");
pthread_mutex_unlock(&mutexA);
printf("Q1 release mutexB\n");
return NULL;
}
int main() {
// 创建线程 1
pthread_create(&(tid[0]), NULL, &Q1, NULL );
// 创建线程 2
pthread_create(&(tid[1]), NULL, &P1, NULL);
pthread_join(tid[0], NULL);
pthread_join(tid[1], NULL);
return 0;
}
结果也是我想要的
P1 get mutexA
Q1 get mutexB
P1 release mutexA
P1 get mutexB
P1 release mutexB
Q1 get mutexA
Q1 release mutexA
Q1 release mutexB