Multithreading 线程在同一进程中的独立性如何?

Multithreading 线程在同一进程中的独立性如何?,multithreading,language-agnostic,Multithreading,Language Agnostic,现在,这可能是一个非常新的问题,但我没有多线程编程的经验,我还没有完全理解线程与进程相比是如何工作的 当我机器上的某个进程挂起时,比如说它正在等待某个永远不会出现的IO或类似的东西,我可以终止并重新启动它,因为其他进程不会受到影响,例如,仍然可以操作我的终端。当然,这是非常明显的 我不确定进程内的线程是否也一样:如果一个线程挂起,其他线程是否不受影响?换句话说,我可以运行一个“看门狗”线程来管理其他线程,例如杀死和重新创建挂起的线程吗?例如,如果我有一个线程池,我不想因为偶尔的挂起而耗尽它。如果

现在,这可能是一个非常新的问题,但我没有多线程编程的经验,我还没有完全理解线程与进程相比是如何工作的

当我机器上的某个进程挂起时,比如说它正在等待某个永远不会出现的IO或类似的东西,我可以终止并重新启动它,因为其他进程不会受到影响,例如,仍然可以操作我的终端。当然,这是非常明显的


我不确定进程内的线程是否也一样:如果一个线程挂起,其他线程是否不受影响?换句话说,我可以运行一个“看门狗”线程来管理其他线程,例如杀死和重新创建挂起的线程吗?例如,如果我有一个线程池,我不想因为偶尔的挂起而耗尽它。

如果一个线程挂起,其他线程将继续执行。但是,如果挂起的线程已经锁定了信号量、临界段或其他类型的同步对象,而另一个线程试图锁定同一个同步对象,那么现在就有两个死锁线程


可以从一个线程监视其他线程。取决于您的平台,有一些可应用的API:我指的是那些您没有说明编写操作系统的API。

您没有提到平台,但就我而言,NT内核以这种方式独立调度线程,而不是进程和威胁线程。这在其他平台上可能不是,也不是真的(有些平台,如Windows 3.1,不使用抢占式多线程,如果一个线程进入无限循环,则一切都会受到影响)。

简单的答案是肯定的

通常情况下,线程中的代码会自行处理这种情况。大多数情况下,许多执行可能挂起的操作的API都有自己的超时特性

或者,线程不仅会等待可能挂起的操作,还会等待计时器。如果计时器首先发出信号,则操作已挂起


因为要使看门狗线程在这种情况下有用,需要其他线程中的代码进行一些合作,让线程本身设置超时比看门狗更有意义。

线程彼此独立地进行调度。因此,您确实可以停止并重新启动挂起的线程。线程不在单独的地址空间中运行,因此行为不正常的线程仍然可以覆盖内存或获取同一进程中其他线程所需的锁

线程是独立的,但是进程和线程之间有区别,也就是说,在进程的情况下,操作系统不仅仅是“杀死”它。之后它也会清理干净

如果您开始终止似乎挂起的线程,很可能会使资源处于锁定状态或类似状态,如果您对进程执行相同操作,操作系统会为您关闭这些资源

例如,如果您打开一个文件进行写入,并开始生成数据并将其写入该文件,而该线程现在挂起,无论出于何种原因,终止该线程都会使该文件保持打开状态,并且很可能处于锁定状态,直到您关闭整个程序

所以你的问题的真正答案是:不,你不能用艰难的方式杀死线程


如果你只是要求一个线程关闭,那就不同了,因为这时线程仍然处于控制之中,可以在终止之前清理和关闭资源,但是调用一个类似“KillThread”的API函数或者类似的方法是不好的。

Java文档中对终止和挂起线程的一些陷阱有一个非常好的概述,解释了为什么不推荐使用这些方法。基本上,如果您希望能够杀死一个线程,那么您必须非常非常小心地使其工作而不会出现某种损坏。如果一个线程被挂起,可能是因为一个bug…在这种情况下,杀死它可能会导致腐败


如果您需要能够杀死东西,请使用进程。

这是一个很好的答案,特别是线程与进程的对比。简言之,操作系统在一个进程之后进行清理,而在一个线程之后不会进行清理!谢谢,我的问题在概念上比具体的操作系统/语言/API更重要