Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/multithreading/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 跨线程的信号槽_C++_Multithreading_Qt - Fatal编程技术网

C++ 跨线程的信号槽

C++ 跨线程的信号槽,c++,multithreading,qt,C++,Multithreading,Qt,假设我有一个类cWorker:public QObject,它包含一个插槽listen()。此对象将移动到单独的线程 主窗口包含一个类GLWidget:public QGLWidget,它有一个信号请求() 如何跨两个线程连接信号插槽?它应该是直截了当的,但我找不到任何关于这个的示例代码。谢谢 int main(int argc, char *argv[]) { cWorker* worker = new cWorker(); QThread* thread = new QThread; w

假设我有一个
类cWorker:public QObject
,它包含一个
插槽listen()
。此对象将移动到单独的线程

主窗口包含一个
类GLWidget:public QGLWidget
,它有一个
信号请求()

如何跨两个线程连接信号插槽?它应该是直截了当的,但我找不到任何关于这个的示例代码。谢谢

int main(int argc, char *argv[])
{

cWorker* worker = new cWorker();

QThread* thread = new QThread;
worker->moveToThread(thread);

QObject::connect(thread, SIGNAL(started()), worker, SLOT(work()) );

thread->start();


QApplication a(argc, argv);
MainWindow w;

GLWidget *my_gl_widget = w.findChild<GLWidget*>("widget");


// THIS DOESN'T WORK
QObject::connect(my_gl_widget, SIGNAL( request() ), worker, SLOT( listen() ));


w.show();

return a.exec();
intmain(intargc,char*argv[])
{
cWorker*worker=新cWorker();
QThread*thread=新的QThread;
辅助线程->移动到线程(线程);
连接(线程、信号(已启动())、工作线程、插槽(工作());
线程->开始();
质量保证申请a(argc、argv);
主窗口w;
GLWidget*my_gl_widget=w.findChild(“widget”);
//这不管用
连接(my_gl_小部件,信号(request()),工作程序,插槽(listen());
w、 show();
返回a.exec();

}

当您在不同的线程中连接两个
QObject
时,
Qt
始终使用
QueuedConnection
。这意味着当发出信号时,Qt将向另一个对象发送事件

问题是,在退出循环之前,
Qt
无法传递事件

为了能够处理事件,您需要a)在
cWorker::work
中中断
无限循环
,或者b)在那里调用
processEvents

a) 要中断循环,可以使用
QTimer
。因此,不是:

while (true) do something;
你将有:

void onTimer()
{
 do something()
}
b) 如果需要在那里执行持久性操作(计算等),可以使用

以下是来自以下站点的
processEvents
说明:

处理调用线程的挂起事件的时间为maxtime毫秒,或者直到没有更多的事件要处理为止,以较短的时间为准。 您可以在程序忙于执行长操作(例如复制文件)时偶尔调用此函数。

结论:
无限循环是您问题的原因。您可以确保:如果删除此行,将调用插槽
listen

连接(线程、信号(已启动())、工作线程、插槽(工作())


在不同线程中连接两个
QObject
s时,
Qt
始终使用
QueuedConnection
。这意味着当发出信号时,Qt将向另一个对象发送事件

问题是,在退出循环之前,
Qt
无法传递事件

为了能够处理事件,您需要a)在
cWorker::work
中中断
无限循环
,或者b)在那里调用
processEvents

a) 要中断循环,可以使用
QTimer
。因此,不是:

while (true) do something;
你将有:

void onTimer()
{
 do something()
}
b) 如果需要在那里执行持久性操作(计算等),可以使用

以下是来自以下站点的
processEvents
说明:

处理调用线程的挂起事件的时间为maxtime毫秒,或者直到没有更多的事件要处理为止,以较短的时间为准。 您可以在程序忙于执行长操作(例如复制文件)时偶尔调用此函数。

结论:
无限循环是您问题的原因。您可以确保:如果删除此行,将调用插槽
listen

连接(线程、信号(已启动())、工作线程、插槽(工作())



你怎么知道它不起作用?
connect
返回什么?它输出什么错误?您是否检查了
my\u gl\u widget
是否不为空?为什么在
main窗口中没有返回
GLWidget
的函数?在这种情况下使用
QObject::findChild
是很愚蠢的。它编译并运行,插槽永远不会执行。回答我的其他三个问题和thuga的问题。我只是在插槽中放了一个cout。你怎么知道它不起作用?
connect
返回什么?它输出什么错误?您是否检查了
my\u gl\u widget
是否不为空?为什么在
main窗口中没有返回
GLWidget
的函数?在这种情况下,使用
QObject::findChild
是很愚蠢的。它编译并运行,插槽永远不会执行。回答我的其他三个问题和thuga的问题。我只是在插槽中放了一个cout。真的。谢谢这是我的问题:我正在运行主线程,以最大60Hz的频率渲染glwindow,并以1kHz的频率渲染工作线程。工作线程包含顶点数据和对其进行的连续操作。paintGL()中需要顶点数据。调用paintGL()时,将顶点数据从辅助线程复制/传递到主线程的最佳方法是什么?我认为信号槽机制最好,但现在似乎不是这样?只是为了确保我理解正确:我应该在无限while循环中放入
processEvents
?如果复制顶点数据的时间长于
maxtime
,会发生什么情况?似乎应该有一种更好的方法来在连续运行的线程之间交换数据。在大多数情况下,只有在发送少量数据或传输时间不紧迫时,才需要使用信号槽。但是如果它对您有效,那么是的,您只需要向循环中添加
processEvents
。使用另一种重载方法
processEvents
,它不需要
maxtime
。我也会考虑共享数据和
QMutex
。此外,你可能还想阅读,事实上。谢谢这是我的问题:我正在运行主线程,以最大60Hz的频率渲染glwindow,并以1kHz的频率渲染工作线程。工作线程包含顶点数据和对其进行的连续操作。paintGL()中需要顶点数据。调用paintGL()时,将顶点数据从辅助线程复制/传递到主线程的最佳方法是什么?我认为信号槽机制是最好的,但是