我使用RedHat 7.4,GCC 4.8.5和Qt 4.8.5进行开发和编译。代码必须进行静态链接,然后在运行Scientific Linux release 6.7的虚拟机上执行。为了避免依赖于更新的GLIBC >= 2.4,使用了memcpy-Wrap。
以下是我的最小工作示例:
以下行为在Scientific-Linux系统上被观察到:
以下是我的最小工作示例:
#include <iostream>
#include <unistd.h>
#include <QtCore>
#include <QThread>
__asm__(".symver memcpy, memcpy@GLIBC_2.2.5");
extern "C" {
void *__wrap_memcpy(void *dest, const void *src, size_t n) { return memcpy(dest, src, n); }
}
class Worker : public QThread {
void run() {
std::cout << "WORKER: Started." << std::endl;
QObject::connect(this, SIGNAL(finished()), QCoreApplication::instance(), SLOT(quit()));
int i=0;
while(i++<3) {
std::cout << "WORKER: I am running." << std::endl;
usleep(1e6);
}
std::cout << "WORKER: Finished." << std::endl;
}
};
int main(int argc, char** argv) {
std::cout << "MAIN: Init QCoreApplication" << std::endl;
QCoreApplication qtApplication(argc, argv);
std::cout << "MAIN: Init Worker" << std::endl;
Worker myWorker;
myWorker.start();
std::cout << "MAIN: Start Event-Loop." << std::endl;
qtApplication.exec();
std::cout << "MAIN: Event-Loop finished." << std::endl;
return 0;
}
这段代码是在RedHat系统上编译的
g++ -I$QTD/mkspecs/linux-g++ -I$QTD/include -I$QTD/include/QtCore -o mwe mwe.cpp -Wl,--wrap=memcpy -L$QTD/lib/ -lQtCore -lQtNetwork -lglib-2.0 -lrt -lpthread -ldl -lz
这里的$QTD是我的Qt-4.8.5安装路径。
在Red-Hat系统上,我们期望并观察到以下行为:
MAIN: Init QCoreApplication
MAIN: Init Worker
MAIN: Start Event-Loop.
WORKER: Started.
WORKER: I am running.
WORKER: I am running.
WORKER: I am running.
WORKER: Finished.
MAIN: Event-Loop finished.
以下行为在Scientific-Linux系统上被观察到:
MAIN: Init QCoreApplication
MAIN: Init Worker
MAIN: Start Event-Loop.
WORKER: Started.
WORKER: I am running.
WORKER: I am running.
WORKER: I am running.
WORKER: Finished.
然后这个应用程序永远无法完成。
在Red-Hat系统中,似乎工作线程的完成信号与核心应用程序的退出槽相连。但在Scientific-Linux系统中似乎没有发生这种情况。请问有什么建议可以解决这个问题并如何进行调试?
Qt::DirectConnection
类型的信号/槽连接。我猜测你的信号已经被发射了,但是槽没有被调用,因为qtApplication.exec();
阻塞了主事件循环。 - vahancho