我写的一个应用这块输入从两个 istreams.

从读者 istream 是同步(封锁)呼叫,因此,我决定创建两个 Boost::threads做阅读。

任何一个这些线可以得到的"末端"(基于一些收到的意见),以及一次"结束"是达到,这两个输入流的停止接收。不幸的是,我不知道会这样做。

因此,我不能 join() 在两个线程,因为只有一条螺纹(不可能规定的其中一个)实际上将返回(疏导).

我必须以某种方式强制其他退出,但它是阻止在等待输入,因此它无法自己决定是时候回报(条件的变数或者什么不是)。

是他们的一种方法:

  • 发送一个信号提升::线,或
  • 强制 istream "失败",或者
  • 杀了一个提升::线?

注:

  • 一个的 istreamscin
  • 我试图重新启动该进程,所以我不能接近输入流的一种方式,禁止重置他们。

编辑:

  • 我知道时"结束"是达到了,我不知道哪个线程已经成功完成,它需要被杀死。其杀死,我需要找出(或不同的战略对于阅读,从istream).
  • 我需要线退出和清理正确:(

谢谢!

有帮助吗?

解决方案

我不认为有一种方法可做到这一交叉平台,但pthread_cancel应该是你寻找。有一个提升螺纹,你可以得到的 native_handle 从一个线程,并呼吁pthread_cancel。

此外一个更好的办法可能是使用的提高 asio 相当于一个选择呼吁多个文件。这样一个线程将被封锁在等待输入,但是它可能来自或输入流。我不知道它是多么容易做这样的事情与iostreams虽然。

其他提示

是的,有的是!

boost::thread::terminate() 会做这份工作给你的规格。

它会引起的有针对性的螺纹扔一个例外。假设这是未捕获的,堆叠会不妨恰当地摧毁了所有的资源和终止线执行。

终止不是即时的。(错误的线运行的是在那一刻,反正。)

它发生在预定的条件下最方便的你能打电话时 boost::this_thread::sleep();, 你可能有线做的周期性。

如果一个提高线被阻止在一个i/o操作(例如 cin>>whatever), boost::thread::terminate() 会不会杀了的螺纹。 cin i/o不是一个有效的终止点。抓住22.

好了linux上,我利用pthread_signal(SIGUSR1),因为它中断blocking IO.有没有这样的呼吁windows因为我发现的时移植我的代码。只有一个废弃的一个在座的阅读的呼吁。在windows你必须明确定义的一个事件,就会打断你的阻断呼吁。所有有这种东西(据我所知)作为一个通用的方式中断blocking IO.

所提高。线设计处理这个通过管理以及确定中断点。我不知道刺激。asio嗯,看来你不想要依靠它。如果你不想重构使用非阻挡的范例,你可以做什么正在使用之间的事情无阻塞(投票)和blocking IO.这是什么(伪码?) :

while(!stopped && !interrupted)
{
    io.blockingCall(timeout);
    if(!stopped && !interrupted)
    {
        doSomething();
    }
}

然后你打断你的两个线程和加入他们...

也许这就是简单的你的情况?如果你有一个主线,知道一个线程是结束了你只有靠近IO的其他线?

编辑:通过这种方式我感兴趣的最终解决方案。

我有一个类似的问题,自己已经达到了这个解决方案,而其他一些读者这一问题可能找到有用的:

假设你正在使用的一个条件变量等()命令,重要的是你要知道,在提高,等等()声明是一个自然中断点。所以刚把一个试/抓块代码等待发言,并允许的功能终止通常在你抓块。

现在,假设你有一个容器用你的线指针,迭代过你的线指针和呼叫中断()对每一线,随后通过加入().

现在所有的你的线将终止优雅,任何提高相关的记忆清理工作应该干净。

而不是试图杀死你的纹,你总是可以tryjoin线相反,如果它失败了,你加入另一个代替。(假设你总是能够加入至少一个你的两个线).

在提升:线你在寻找 timed_join 功能。

如果你想看到正确的答案,但是,这将是使用非阻io定时等待。让你得到的流动结构的同步io,与非阻挡的步io.

你谈论的阅读的形式istream,但istream是只有一个接口。为stdin,你可以fclose的stdin文件描述中断阅读。至于其他的,它取决于一个在那里你读。

它似乎线是不会帮你做什么你要在一个简单的方式。如果提升。Asio是不是你喜欢的,可以考虑使用 select().

这个想法是让两个文件的描述符和使用 select() 告诉你他们有输入提供。该文件描述 cin 通常是 STDIN_FILENO;如何获得另外一个取决于你具体情况(如果它是一个文件,只是 open() 这不是使用 ifstream).

呼叫 select() 在一个循环中找到了其输入读,而当你要停止,只是打破的循环。

窗下,使用QueueUserAPC排队一个进程,这会引发一个例外。这种做法正常工作对我来说。

然而:我刚刚发现,提高互斥等不是"可报警"on win32,所以QueueUserAPC不能中断。

很晚了,但是在窗口(以及它的前体样虚拟机或RSX对于那些记住这样的事情)我们使用类似ReadFileEx与完成日常的信号时完成,并CancelIO如果阅读需要被取消了早。

Linux/BSD有一个完全不同的基础API它不是灵活的。使用pthread_kill发送一个信号对我的作品,这将停止阅读/开放运作。

这是值得执行不同的代码,在这一领域为每个平台,恕我直言。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top