Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/batch-file/6.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
QT分叉_Qt_Fork - Fatal编程技术网

QT分叉

QT分叉,qt,fork,Qt,Fork,使用QtCreator为软件创建更高的界面。 基本上有一组按钮来调整和输入,一个启动和停止作业 buttons,我的问题来自一个无限循环,它冻结了显示,所以我想到了使用fork(),这样循环就必须与主程序竞争,而不是消耗整个资源(没有多线程),但是程序崩溃了: [xcb] Unknown sequence number while processing queue [xcb] Most likely this is a multi-threaded client and XInitThreads

使用QtCreator为软件创建更高的界面。 基本上有一组按钮来调整和输入,一个启动和停止作业 buttons,我的问题来自一个无限循环,它冻结了显示,所以我想到了使用fork(),这样循环就必须与主程序竞争,而不是消耗整个资源(没有多线程),但是程序崩溃了:

[xcb] Unknown sequence number while processing queue
[xcb] Most likely this is a multi-threaded client and XInitThreads has not
been called
[xcb] Aborting, sorry about that.
a.out: ../../src/xcb_io.c:274: poll_for_event: Assertion 
`!xcb_xlib_threads_sequence_lost' failed.
调用循环的函数称为“开”,“关”应该退出分叉进程

//in button 'ON' func
ps = fork();
if(getpid() == ps)
{
    while(1)
    {
        strcpy(word, charset(minlength, maxlength, N));
        ui->pass->setText(word);//operation on the display
        ....SNIP
    }
}

//In button 'OFF' func
if(getpid() == ps)
    exit(0);

我真的想问的是,怎样才能正确地开始一段时间(1),并能够在不使用QT冻结窗口的情况下中断、退出或从中返回,谢谢。

您可能会在这里崩溃:

ui->pass->setText(word);//operation on the display  
与在Qt中一样,您不能直接从非UI线程更改UI。仅来自信号和插槽机制

不冻结UI的正确方法显然是在另一个线程中计算冗长的操作

您可以通过以下几种方式实现这一点:

一种是通过对QObject类进行子分类来创建“worker对象”,它将执行所有繁重的操作。您可以创建新的
QThread
对象,该对象应该在您需要对象的时候一直存在。并使用
QObject::moveToThread
方法将创建的对象移动到新线程。要控制worker对象,您应该从对象发送信号,并通过信号槽机制调用其插槽。如果您直接调用它们,它们将在调用线程中执行(所以不要在UI线程中执行类似worker->startHeavyJob();的操作)。而是在UI中发出信号(emit sigStartHeavyStuff();),并将其连接到工作对象的插槽(slotDoHeavyStuff();)

如果您不想为此烦恼(如果操作非常小) -您可以使用在无限while循环中处理UI事件循环中的事件


另一种方法是使用框架在单独的线程中运行函数,该线程管理自身。线程取自线程池,由Qt管理。这种方法看起来像是您想要做的事情。尽管您仍然只能通过信号和插槽访问UI对象。

我看到了导致您冻结的代码中的一个大问题:在循环中,您从不让Qt处理任何东西。您需要允许Qt运行它的事件循环。最简单的方法是在循环中使用
QApplication::processEvents()

我也不喜欢
while(1)
循环,原因有二。首先,它可以吃掉等待事情发生的机器循环。我怀疑您是否真的需要尽可能快地运行代码,您可能会在循环中睡上一觉

另一个问题是很难突破。更干净的方法应该是这样的

void MyClass::on_pushButton_ON_clicked()
{
    MyClass::done = false;  // this is a class attribute
    while (!MyClass::done) {
        QApplication::processEvents();
        //...
    }
}

void MyClass::on_pushButton_OFF_clicked()
{
    MyClass::done = true;
}

当你说“无多线程”时,你实际上是在通过分叉一个进程(内存空间+线程)来生成更多线程。我真的很失望,因为我不想深入到QTthreads的世界中,但是循环中包含的processEvents()例程修复了我的问题,谢谢。关于QtConcurrent::run()我必须这样使用我的成员函数:
QFuture p1=QtConcurrent::run(this,&MainWindow::loop)从on_按钮on_clicked()功能调用。它必须是MainWindow的一个成员,这样我才不会弄乱Ui,这给我带来了极大的痛苦。只是关于睡眠操作的一个问题:它不会释放程序内部的资源,而只能用于其他进程,考虑到它仍然是单线程的事实?我进入了线程,这就引导我进入了我从未学习过的信号和插槽系统,所以感谢你的指导。