本人刚开始接触多线程,尝试写了段程序,但是结果不对,我用计数器每隔100毫秒执行一次显示:即
主线程代码:
QMutex mutex;
void MyClass::handleProcess(){
QVector<QThread*> threads;
m_timer = new QTimer(this);
connect(m_timer, SIGNAL(timeout()), this, SLOT(onTimeOut()));
m_timer->setTimerType(Qt::PreciseTimer);
for (int k = 0; k<3; k++){
QThread *imageThread = new QThread;
MyImage *myImage = new MyImage(k);
myImage->moveToThread(imageThread);
connect(this, SIGNAL(imageCreate()), myImage, SLOT(startImageCreate()));
threads.append(imageThread);
}
m_timer->start(100);
}
void MyClass::onTimeOut(){
for (int i = 0; i<9; i++)
threads[i]->start();
emit imageCreate();
}
子线程代码:
class MyImage : public QObject
{
Q_OBJECT
public:
explicit MyImage(int index = 0);
public slots :
void startImageCreate(int index);
private:
int index;
};
extern QMutex mutex;
MyImage::MyImage(int No) :QObject()
{
index = No ;
}
void MyImage::startImageCreate(int index)
{
mutex.lock();
qDebug() << index << " running..\n";
mutex.unlock();
}
各位大神,我的主要目的就是想依次的执行线程,请问怎么加互斥量才会解决这个问题呢,在线等,拜谢!
6 个解决方案
#1
多线程没法按照你的要求依次调用,如何调用系统会有一个调度策略,按照线程优先级或者系统资源使用率等来调度线程,你所能做的是保证你的代码在多线程环境下运行不出错,使用互斥量是为了保证锁住的代码在同一时间只有一个线程运行,而不会是多个线程同时运行该段代码导致结果出错。
#2
如果,这九个线程结束后,都会通过信号量-槽的方式调用主线程里的函数,也就是九个线程同时访问主线程里的响应函数,即使,我用vectro<int> vecTemp , 九个ID,分别存储数据到对应的vecTemp[ID]下,请问这种情况,我需要对主线程里的响应函数使用互斥量嘛?
#3
我给你发动了一下.相信应该可以理解.
没有使用锁,使用的信号量.它正好可以满足你的需求.
没有使用锁,使用的信号量.它正好可以满足你的需求.
#include <QCoreApplication>
#include <QSemaphore>
#include <QTimer>
#include <QThread>
#include <QDebug>
class MyImage : public QObject
{
Q_OBJECT
public:
explicit MyImage(int index = 0);
public slots :
void startImageCreate();
private:
int index;
};
static QSemaphore sem(1);
MyImage::MyImage(int No) :QObject()
{
index = No ;
}
void MyImage::startImageCreate()
{
sem.acquire(index); //获取资源,
qDebug() << "index:" << index;
sem.release(index+1);//释放多一个的资源,刚好可以,让下一个acquire获取成功.
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<QThread*> threads;
for (int k = 1; k <= 9; k++) //从一开始.到9结束
{
QThread *imageThread = new QThread;
MyImage *myImage = new MyImage(k);
imageThread->start(); //启动线程
myImage->moveToThread(imageThread);
threads.append(imageThread);
//用QTimer来触发槽,和连接一个信号再发出信号一个效果,都是Qt::QueuedConnection效果.
QTimer::singleShot(0, myImage, SLOT(startImageCreate()));
}
return a.exec();
}
#include "main.moc"
#4
你好,这段代码是只执行一次的显示,即一次1到9的打印,如果想反复打印的话,是不是需要把QTimer::singleShot(0, myImage, SLOT(startImageCreate()));放入一个定时器响应函数中呢?
#5
#include <QCoreApplication>
#include <QEventLoop>
#include <QSemaphore>
#include <QTimer>
#include <QThread>
#include <QDebug>
class MyImage : public QThread
{
Q_OBJECT
public:
explicit MyImage(QSemaphore *sem, int index = 0) : sem(sem), index(index){}
~MyImage() { this->exit(); this->wait(); }
public slots :
void startImageCreate()
{
sem->acquire(index);
qDebug() << "index:" << index;
sem->release(index+1);
this->exit();
}
private:
QSemaphore *sem;
int index;
};
class Process1_9
{
public:
Process1_9() : sem(1){}
~Process1_9(){}
void process()
{
QEventLoop loop;
QVector<MyImage*> threads;
for (int k = 1; k <= 9; k++)
{
MyImage *myImage = new MyImage(&sem, k);
if (k == 9)
{
QObject::connect(myImage, SIGNAL(finished()), &loop, SLOT(quit()));
}
threads.append(myImage);
myImage->start();
myImage->moveToThread(myImage);
QTimer::singleShot(0, myImage, SLOT(startImageCreate()));
}
loop.exec();
qDeleteAll(threads);
}
private:
QSemaphore sem;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for (int i = 0; i < 3; ++i)
{
Process1_9 p;
p.process();
qDebug() << "===times:" << i + 1;
QEventLoop loop;
QTimer::singleShot(1000, &loop, SLOT(quit()));
loop.exec();
}
return a.exec();
}
#include "main.moc"
就是把1-9的执行再封装一下呀. 方式很多,我随便写的.你看着修改吧.
#6
你好,这个确实能够实现依次显示,但是,我发现它是阻塞的方式,也就是只有等依次显示完成,才能启动主界面,是这样的,我的程序是,每个线程中保存的数据是图像,每次九个都执行完一次后,这些图像需要在主线程里显示出来,之后九个线程在继续保存新的图像,继续在主线程里显示,我改怎么修改这种阻塞的方式呢,多谢大神~
#1
多线程没法按照你的要求依次调用,如何调用系统会有一个调度策略,按照线程优先级或者系统资源使用率等来调度线程,你所能做的是保证你的代码在多线程环境下运行不出错,使用互斥量是为了保证锁住的代码在同一时间只有一个线程运行,而不会是多个线程同时运行该段代码导致结果出错。
#2
如果,这九个线程结束后,都会通过信号量-槽的方式调用主线程里的函数,也就是九个线程同时访问主线程里的响应函数,即使,我用vectro<int> vecTemp , 九个ID,分别存储数据到对应的vecTemp[ID]下,请问这种情况,我需要对主线程里的响应函数使用互斥量嘛?
#3
我给你发动了一下.相信应该可以理解.
没有使用锁,使用的信号量.它正好可以满足你的需求.
没有使用锁,使用的信号量.它正好可以满足你的需求.
#include <QCoreApplication>
#include <QSemaphore>
#include <QTimer>
#include <QThread>
#include <QDebug>
class MyImage : public QObject
{
Q_OBJECT
public:
explicit MyImage(int index = 0);
public slots :
void startImageCreate();
private:
int index;
};
static QSemaphore sem(1);
MyImage::MyImage(int No) :QObject()
{
index = No ;
}
void MyImage::startImageCreate()
{
sem.acquire(index); //获取资源,
qDebug() << "index:" << index;
sem.release(index+1);//释放多一个的资源,刚好可以,让下一个acquire获取成功.
}
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QVector<QThread*> threads;
for (int k = 1; k <= 9; k++) //从一开始.到9结束
{
QThread *imageThread = new QThread;
MyImage *myImage = new MyImage(k);
imageThread->start(); //启动线程
myImage->moveToThread(imageThread);
threads.append(imageThread);
//用QTimer来触发槽,和连接一个信号再发出信号一个效果,都是Qt::QueuedConnection效果.
QTimer::singleShot(0, myImage, SLOT(startImageCreate()));
}
return a.exec();
}
#include "main.moc"
#4
你好,这段代码是只执行一次的显示,即一次1到9的打印,如果想反复打印的话,是不是需要把QTimer::singleShot(0, myImage, SLOT(startImageCreate()));放入一个定时器响应函数中呢?
#5
#include <QCoreApplication>
#include <QEventLoop>
#include <QSemaphore>
#include <QTimer>
#include <QThread>
#include <QDebug>
class MyImage : public QThread
{
Q_OBJECT
public:
explicit MyImage(QSemaphore *sem, int index = 0) : sem(sem), index(index){}
~MyImage() { this->exit(); this->wait(); }
public slots :
void startImageCreate()
{
sem->acquire(index);
qDebug() << "index:" << index;
sem->release(index+1);
this->exit();
}
private:
QSemaphore *sem;
int index;
};
class Process1_9
{
public:
Process1_9() : sem(1){}
~Process1_9(){}
void process()
{
QEventLoop loop;
QVector<MyImage*> threads;
for (int k = 1; k <= 9; k++)
{
MyImage *myImage = new MyImage(&sem, k);
if (k == 9)
{
QObject::connect(myImage, SIGNAL(finished()), &loop, SLOT(quit()));
}
threads.append(myImage);
myImage->start();
myImage->moveToThread(myImage);
QTimer::singleShot(0, myImage, SLOT(startImageCreate()));
}
loop.exec();
qDeleteAll(threads);
}
private:
QSemaphore sem;
};
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
for (int i = 0; i < 3; ++i)
{
Process1_9 p;
p.process();
qDebug() << "===times:" << i + 1;
QEventLoop loop;
QTimer::singleShot(1000, &loop, SLOT(quit()));
loop.exec();
}
return a.exec();
}
#include "main.moc"
就是把1-9的执行再封装一下呀. 方式很多,我随便写的.你看着修改吧.
#6
你好,这个确实能够实现依次显示,但是,我发现它是阻塞的方式,也就是只有等依次显示完成,才能启动主界面,是这样的,我的程序是,每个线程中保存的数据是图像,每次九个都执行完一次后,这些图像需要在主线程里显示出来,之后九个线程在继续保存新的图像,继续在主线程里显示,我改怎么修改这种阻塞的方式呢,多谢大神~