有可能弄断一根纺线吗?

Is it possible to kill a spinning thread?

本文关键字:一根 有可能弄      更新时间:2023-10-16

我用ZThreads来说明这个问题,但是我的问题适用于PThreads, Boost Threads和c++中的其他线程库。

class MyClass: public Runnable
{
 public:
  void run()
   {
      while(1)
      {
      }
   }
}

我现在像这样启动它:

MyClass *myClass = new MyClass();
Thread t1(myClass);

现在可以杀死(暴力如果必要的话)这个线程吗?我可以这样做,而不是无限循环,我有一个Thread::Sleep(100000),如果它阻塞。但是我可以终止一个正在旋转的线程(进行计算)吗?如果是,怎么做?如果不是,为什么不呢?

就Windows而言(来自MSDN):

TerminateThread是一个危险的函数,应该只在最极端的例子。您应该只在以下情况下调用TerminateThread确切地知道目标线程在做什么,就可以控制所有的线程目标线程当时可能正在运行的代码终止。例如,TerminateThread会导致以下问题:

If the target thread owns a critical section, the critical section will not be released.
If the target thread is allocating memory from the heap, the heap lock will not be released.
If the target thread is executing certain kernel32 calls when it is terminated, the kernel32 state for the thread's process could be inconsistent.
If the target thread is manipulating the global state of a shared DLL, the state of the DLL could be destroyed, affecting other users of the DLL.

Boost当然没有线程终止函数

这类问题的一般解决方案可以在Herb Sutter的文章中找到:更喜欢使用活动对象而不是裸线程

这允许你有这样的东西(节选自文章):

class Active {
public:
  typedef function<void()> Message;
private:
  Active( const Active& );           // no copying
  void operator=( const Active& );    // no copying
  bool done;                         // le flag
  message_queue<Message> mq;        // le queue
  unique_ptr<thread> thd;          // le thread
  void Run() {
    while( !done ) {
      Message msg = mq.receive();
      msg();            // execute message
    } // note: last message sets done to true
  }

在活动对象析构函数中可以这样:

~Active() {
    Send( [&]{ done = true; } ); ;
    thd->join();
  }

此解决方案促进了干净线程函数的存在,并避免了与不干净线程终止相关的所有其他问题。

可以强制终止线程,但是执行此操作的调用将是特定于平台的。例如,在Windows下,你可以使用TerminateThread函数。

请记住,如果您使用TerminateThread,线程将没有机会释放它正在使用的任何资源,直到程序终止。

如果你需要终止一个线程,可以考虑使用进程。

特别是如果你告诉我们你的"线程"是一个while (true)循环,它可能会休眠很长一段时间,执行必要的阻塞操作。对我来说,这表明了一个类似过程的行为。

进程可以在几乎任何时间以多种方式终止,并且总是以干净的方式终止。它们还可以在发生事故时提供更高的可靠性。

现代操作系统提供了一系列进程间通信设施:套接字、管道、共享内存、内存映射文件……它们甚至可以交换文件描述符。

好的操作系统有写时复制机制,所以fork进程很便宜。

请注意,如果您的操作可以以非阻塞的方式进行,那么您应该使用类似轮询的机制。Boost::asio可能会有所帮助。

可以使用TerminateThread() API,但不建议使用。

详情见:http://msdn.microsoft.com/en-us/library/windows/desktop/ms686717 (v = vs.85) . aspx

正如人们已经说过的,没有可移植的方法来终止线程,在某些情况下根本不可能。如果你可以控制代码(即可以修改它),最简单的方法之一是设置一个布尔变量,线程定期检查,如果设置,则尽快终止线程。

你就不能在

do {
  //stuff here
} while (!abort)

并且在计算之间偶尔检查一次标志,如果它们很小且不太长(如上面的循环),或者在中间检查一次标志,如果计算很长则中止计算?

不确定其他库,但在pthread库中pthread_kill函数可用pthread_kill

是,

定义keepAlive变量为int。初始设置keepAlive=1的值

class MyClass: public Runnable
{
 public:
  void run()
   {
      while(keepAlive)
      {
      }
   }
}

现在,当你想要杀死线程时,只需设置keepAlive=0的值。

Q 。这是如何工作的?

。线程将处于活动状态,直到函数连续执行。所以Terminate函数很简单。设置变量的值为0 &它会中断,导致线程终止。[This is the safest way I found till date] .