最近,我在本标题中记得这个问题。 我尝试过使用QThread :: terminate(),但我无法停止 线程,它处于一个死循环中(比方说,while(1))。
非常感谢。
答案 0 :(得分:12)
终止线程是停止异步操作的简单解决方案,但通常是一个坏主意:线程可能正在进行系统调用,或者在终止时可能正在更新数据结构,这可能是让程序甚至操作系统处于不稳定状态。
尝试将while(1)转换为while(isAlive())并使isAlive()在您希望线程退出时返回false。
答案 1 :(得分:1)
QThreads如果在终止期间“自然地”完成就会陷入僵局。
例如在Unix中,如果线程正在等待“读取”调用,则终止尝试(Unix信号)将使“读取”调用在线程被销毁之前用错误代码中止。
这意味着线程在终止时仍然可以到达它的自然出口点。当它这样做时,由于某些内部互斥锁已被“终止”调用锁定,因此会发生死锁。
我的解决方法是确保线程从不在终止后返回。
while( read(...) > 0 ) {
// Do stuff...
}
while( wasTerminated )
sleep(1);
return;
wasTerminated 这里使用原子注入实际上实现起来有点复杂:
enum {
Running, Terminating, Quitting
};
QAtomicInt _state; // Initialized to Running
void myTerminate()
{
if( _state.testAndSetAquire(Running, Terminating) )
terminate();
}
void run()
{
[...]
while(read(...) > 0 ) {
[...]
}
if( !_state.testAndSetAquire(Running, Quitting) ) {
for(;;) sleep(1);
}
}
答案 2 :(得分:0)
答案 3 :(得分:0)
线程是否致电QThread::setTerminationEnabled(false)
?这将导致线程终止无限期地延迟。
TerminateThread()
的包装器。这个函数接受来自无线程的不尊重,并且往往会在资源泄漏和类似的悬空状态下留下混乱。如果它没有杀死线程,你要么处理僵尸内核调用(很可能是阻塞的I / O),要么在某个地方遇到更大的问题。
答案 4 :(得分:0)
使用未命名的管道
int gPipeFdTest[2]; //create a global integer array
如果您打算创建管道,请使用
if( pipe(gPipeFdTest) < 0)
{
perror("Pipe failed");
exit(1);
}
上面的代码将创建一个管道,其两端有gPipeFdTest [0]用于读取,gPipeFdTest [1]用于写入。你可以做的是在你的运行功能设置中使用select系统调用来读取管道。从您想要运行的地方开始,设置使用写入系统调用进行写入。我已经使用select系统调用来监视管道的读取端,因为它适合我的实施。试着在你的情况下找出所有这些。如果您需要更多帮助,请给我一个嗡嗡声。
编辑:
我的问题和你的一样。我有一段时间(1)循环和我尝试的其他东西需要互斥和其他花哨的多线程mumbo jumbo,这增加了复杂性和调试是噩梦。除了简化代码之外,使用管道使我从这些复杂性中解脱出来。我并不是说这是最好的选择,但就我而言,事实证明它是最好和最干净的选择。在此解决方案之前,我被窃听了我的应用程序。