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
Multithreading 将异常抛出到另一个线程中_Multithreading_C++11_Exception_Posix - Fatal编程技术网

Multithreading 将异常抛出到另一个线程中

Multithreading 将异常抛出到另一个线程中,multithreading,c++11,exception,posix,Multithreading,C++11,Exception,Posix,这不是涉及从一个线程捕获另一个线程抛出的异常的任何问题的重复 我有生成线程的代码,它会自动运行并完成自己的事情 在将来的某个时候,我希望能够在另一个线程中抛出两个异常中的一个(即terminate和interrupt) 一种方法是共享一个变量,让另一个线程定期检查是否应该终止它。我的偏好是不具有它检查的约束(一些代码将独立于执行线程的库,并且不会被编写为检查) 在我的理想解决方案中,在调试时,您可能会发现auto i=1+1抛出异常,因为另一个线程告诉您的线程要抛出异常,而您当时正好在这一行 有

这不是涉及从一个线程捕获另一个线程抛出的异常的任何问题的重复

我有生成线程的代码,它会自动运行并完成自己的事情

在将来的某个时候,我希望能够在另一个线程中抛出两个异常中的一个(即
terminate
interrupt

一种方法是共享一个变量,让另一个线程定期检查是否应该终止它。我的偏好是不具有它检查的约束(一些代码将独立于执行线程的库,并且不会被编写为检查)

在我的理想解决方案中,在调试时,您可能会发现
auto i=1+1
抛出异常,因为另一个线程告诉您的线程要抛出异常,而您当时正好在这一行


有什么方法可以做到这一点吗?

我认为让线程a中的异常被线程B捕获在概念上没有意义,因为异常的核心概念是堆栈的展开,而线程a的堆栈与线程B的堆栈不同

您可以做的是在线程A中抛出异常,让线程A中的异常处理程序捕获异常并通过以某种方式将相关细节通知线程B来处理它,当线程B收到通知时,它可以通过抛出自己的异常来响应,该异常类似于最初在线程A中抛出的异常

至于如何实现通知和数据传输,您可以使用任何常见的跨线程通知/通信机制(共享原子变量和轮询、socketpair、管道、互斥保护的FIFO消息队列等)

在我的理想解决方案中,您可能会遇到这样的情况,调试, 您可能会发现auto i=1+1抛出异常,因为另一个 线程告诉你的线程抛出,这就是你刚才发生的线 要在那个时候出现


我认为这是一个异步异常,我不认为它是由标准C++支持的。微软有他们的(SEH)这样做,但这是一个专有/非标准功能。

是的,有可能在另一个线程中引发异常

我假设你知道为什么在普通程序中不应该这样做的所有理由。但作为测试套件、调试工具或与python内部相关的程序的一部分,这可能会有所帮助

这大概是从


老实说,这真的没有任何意义。C++的异常机制基本上是围绕着展开发生异常的上下文堆栈来组织的。也许你可以试着用这个机制来解释你想要解决的问题,你会得到解决问题的合理方法的建议。通常的答案是:“如果你发现你需要从外部进入以使线程做正确的事情,这意味着你为该线程编写的代码是错误的。为什么它还没有编码为做正确的事情呢?所有线程都必须合作。”在理想世界中,是的,@DavidSchwartz,他们会这样做。但是,如果一个线程正在等待某个API(例如InfiniBand)返回,而它从未返回,那么所有这些广告是否都应该合作并不重要:它们不会。假设您总是处于这样的位置是天真的。确实有处理这样的情况的工具,但跨线程异常不是。如果API支持中断,您只需使用它支持的中断。如果它不支持中断,那么中断就不是解决方案。否则,您必须使用其他工具,例如使用包装器将API隔离到自己的进程中。除了上一段之外,我认为您完全没有抓住要点。有很多方法可以从一个线程到另一个线程获取信息——如果另一个线程正在侦听的话。但是,如果另一个线程没有监听(因为有人编写了一个API,它阻塞了某些内容,并且不等待),这并不重要。关键不是在一个线程中抛出一个异常,然后在另一个线程中捕获它:而是将一个线程注入另一个线程。将我的答案改为“不,这不可能”会更好吗?(顺便说一句,问题的标题是“将异常抛出到另一个线程”,对我来说,这听起来很像“在一个线程中抛出异常,在另一个线程中捕获异常”)听起来很像,但不是真的。一个是
throw Exception()
,后面是另一个线程中的catch。另一个是<>代码> AbthTeRealObjult.SuffExistOutlook()/Cux>是否可以在C++下的另一个线程中引发异常?发问者没有提到python。
import ctypes

def ctype_async_raise(target_tid, exception):
    ret = ctypes.pythonapi.PyThreadState_SetAsyncExc(ctypes.c_long(target_tid), ctypes.py_object(exception))
    # ref: http://docs.python.org/c-api/init.html#PyThreadState_SetAsyncExc
    if ret == 0:
        raise ValueError("Invalid thread ID")
    elif ret > 1:
        # Huh? Why would we notify more than one threads?
        # Because we punch a hole into C level interpreter.
        # So it is better to clean up the mess.
        ctypes.pythonapi.PyThreadState_SetAsyncExc(target_tid, NULL)
        raise SystemError("PyThreadState_SetAsyncExc failed")