如何避免多线程

时间:2015-03-05 10:57:01

标签: c multithreading

我遇到了this question并对this answer留下了深刻的印象。

我真的想听从那个答案的建议,但我无法想象如何做到这一点。 如何避免多线程?

通常情况下,需要同时处理不同的事物(例如,不同的硬件资源或网络),但同时他们需要访问共享数据(如配置,要处理的数据等)。 如何在不使用任何类型的大型状态机或事件循环的情况下解决单线程问题?

我知道,这是一个很大的话题,在Stackoverflow这样的平台上无法作为一个整体回答。我想我应该从提到的答案中阅读建议书,但是现在我想在这里阅读一些意见。

也许值得注意的是,我对C语言中的解决方案很感兴趣。像Java,C ++这样的高级语言,特别是像Qt或类似的框架,简化了这一点,但纯粹的C呢?

非常感谢任何输入。提前谢谢大家

3 个答案:

答案 0 :(得分:3)

您已经提到了事件循环,但我仍然认为这些为许多应用程序提供了多线程的绝佳替代方案,并且如果有必要,在以后添加多线程时也可以作为一个很好的基础。

假设您有一个应用程序需要处理用户输入,套接字上收到的数据,计时器事件和信号,例如:

  • 一个多线程设计是产生不同的线程来等待不同的事件源,让它们在事件到达时在某些全局状态下同步它们的动作。这通常会导致混乱的同步和终止逻辑。

  • 单线程设计将是一个统一的事件循环,它接收所有类型的事件并在它们到达的同一个线程中处理它们。在* nix系统上,这可以使用例如select(2)poll(2)epoll(7)(后者特定于Linux)。最近的Linux版本还提供了signalfd(2)timerfdtimerfd_create(2))和eventfd(2),以便将其他事件类型干净地拟合到此模型中,而对于其他unices,您可以使用各种技巧例如pipe(2)表示事件。一个很好的图书馆提取了大部分内容,libevent,也适用于其他平台。

除了不必立即处理多线程之外,事件循环方法还可以在以后根据性能或其他原因需要添加多线程:您只需让事件处理程序为某些事件生成线程。将所有事件处理放在一个位置通常可以大大简化应用程序设计。

当你确实需要多个线程(或进程)时,它们有助于在它们之间建立狭窄且经过良好测试的接口,例如使用它们。同步队列。事件处理程序的另一种设计是让事件生成线程将事件推送到事件队列,事件处理程序然后从中读取和分派它们。这清楚地区分了程序的各个部分。

答案 1 :(得分:2)

详细了解continuationscontination-passing style(以及CPS转换)。

CPS变换可能是模仿"模拟"多线程。

您可以查看CPC Continuation Passing C ,作者:Juliusz Chroboczek和Gabriel Kerneis),它也是源C变换器的来源。您还可以阅读旧的Appel的书:Compiling with Continuations和Queinnec的书Lisp In Small Pieces

还详细了解event loopscallbacksclosurescall stackstail calls。这些概念与您的疑虑有关。

另请参阅(几乎过时的)setcontext(3) Linux函数以及事件循环中的空闲函数,请参阅this

答案 2 :(得分:1)

您可以使用协同程序实现并发任务。然后,您必须明确地将控制(cpu)传递给另一个协同程序。在一小段延迟之后,它不会被中断自动完成。

http://en.wikipedia.org/wiki/Coroutine