【问题标题】:backgrounding a threaded application with fork()使用 fork() 将线程应用程序后台化
【发布时间】:2011-06-23 02:31:45
【问题描述】:

所以我有一个使用线程的应用程序。现在,当程序第一次启动时,我希望它在它自己后台之前通过设置数据库连接和诸如此类的东西,以便启动程序的任何人/任何人都可以知道启动是否有错误。

我环顾四周,发现一些资源说“不要混合使用 fork 和线程”,而其他人则说在 linux 中的 fork 只会复制主线程而不会影响其他线程。
在后者的情况下(它只是复制主线程),那么线程如何访问文件级(全局)变量?线程是否无法访问分叉进程地址空间中的变量?

最终目标是在创建线程后让应用程序后台运行。如果这是不可能的,我可以在创建线程之前放叉,只是想尽可能晚。

注意:在 fork 时,线程将执行 sleep() 循环,直到主线程将数据放入共享变量以供它们处理。所以如果睡眠被打断,他们不会受到伤害。

【问题讨论】:

    标签: c linux multithreading pthreads fork


    【解决方案1】:

    当进程中的线程调用fork()时,通过复制(1)进程的完整地址空间和(2)调用fork的(一个)线程来创建一个新进程.如果进程中有其他线程,它们不会被复制。这几乎肯定会导致您的程序出现错误。因此建议不要混合使用线程和分叉。

    如果您想创建一个具有多个线程的后台进程,您必须在生成任何其他线程之前对其进行 fork。然后,这两个进程的行为正常,就像任何两个独立的进程一样:一个进程中的线程共享相同的内存,但您的后台线程和前台进程不会共享任何内存(默认情况下)。

    【讨论】:

    • 有道理。我在想也许不同的建议是由于不同的线程实现。叉子只复制主线程,而其他线程没有被复制,他们无法访问叉子的内存是我期望的事情。只是不知道那里是否有一些背景魔法。
    【解决方案2】:

    分叉一个进程会创建两个不同的进程,一个进程中的线程将无法访问第二个进程中的内存。如果你想让不同的进程访问同一个内存,你需要一种叫做共享内存的东西。

    【讨论】:

      【解决方案3】:

      没有办法将线程复制为fork 的一部分,并且当父级退出时,父级的线程将全部终止,因此即使它们可以访问子级的内存,也无济于事。您需要在分叉后创建线程,或使用pthread_atfork 注册将在子进程中重新创建它们的处理程序。我建议您等到 fork 之后再创建线程,因为它更简单、更高效。

      为什么要尽可能地延迟分叉?如果您想在初始化完成之前保持与终端或其他东西的连接,您可以让父进程等待终止,直到子进程(及其线程)完成初始化并准备好“在后台”。可以使用各种同步工具来实现这一点。一个简单的方法是打开一个管道,子进程通过该管道将其输出发送回父进程以显示;父级在此管道上收到 EOF 时可以简单地退出。

      【讨论】:

      • 哇,我觉得愚蠢的是没有想到“先分叉,然后等到孩子初始化后再退出”解决方案。这是一个非常干净和有效的解决方案。谢谢:-)
      猜你喜欢
      • 2014-03-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2022-11-02
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多