【问题标题】:How to handle a fork error for a multithreaded process?如何处理多线程进程的分叉错误?
【发布时间】:2012-02-20 01:01:39
【问题描述】:

我正在处理一个多线程进程,该进程分叉执行另一个进程。有时,如果执行文件不存在,fork 可能会出错。由于这个进程在 fork 之前运行了多个线程,我有几个问题:

  1. 线程是否被复制到派生进程。
  2. 使用多线程进程处理来自 fork 的错误的最佳做法是什么。例如:

    /* in a multithreaded process */
    
    
    pid = fork();
    
    if(pid == 0)
    {
    
        execlp(filename, filename, NULL);
    
        fprintf(stderr, "filename doesn't exist");
    
        /* what do i do here if there's multiple threads running
        from the fork? */
    
        exit(-1);
    }
    

【问题讨论】:

    标签: c multithreading pthreads fork


    【解决方案1】:

    好吧,如果可执行文件不存在,fork 不会出错。在这种情况下,exec 错误。但是,对于您的实际 问题,POSIX 声明fork 创建一个具有单个 线程的新进程,该线程是调用fork 的线程的副本。详情见here

    应使用单个线程创建进程。如果多线程进程调用 fork(),则新进程应包含调用线程及其整个地址空间的副本,可能包括互斥锁和其他资源的状态。

    因此,为避免错误,子进程只能执行异步信号安全操作,直到调用其中一个 exec 函数。

    所以你有什么是好的,如果有点稀疏:-)

    单个线程将在子程序中运行,如果您无法exec 另一个程序,请记录一条消息并退出。

    并且,在基本原理部分,它解释了为什么这样做:

    POSIX 程序员调用 fork() 有两个原因。一个原因是在同一个程序中创建一个新的控制线程(这最初只能在 POSIX 中通过创建一个新进程来实现);另一种是创建一个运行不同程序的新进程。在后一种情况下,对 fork() 的调用很快就会调用其中一个 exec 函数。

    使 fork() 在多线程世界中工作的一般问题是如何处理所有线程。有两种选择。一种是将所有线程复制到新进程中。这会导致程序员或实现处理在系统调用上挂起的线程或可能即将执行不应在新进程中执行的系统调用的线程。另一种选择是只复制调用 fork() 的线程。这造成了进程本地资源的状态通常保存在进程内存中的困难。如果没有调用 fork() 的线程持有资源,则该资源永远不会在子进程中释放,因为其任务是释放资源的线程在子进程中不存在。

    当程序员编写多线程程序时,第一次描述的 fork() 用法,即在同一程序中创建新线程,是由 pthread_create() 函数提供的。因此,fork() 函数仅用于运行新程序,在调用 fork() 和调用 exec 函数之间调用需要某些资源的函数的效果是未定义的。

    【讨论】:

    • fprintf() 不是异步信号安全的,所以你不应该在孩子中调用它。您可以使用带有文件描述符 2 的 write() 向标准错误发送消息。
    猜你喜欢
    • 2021-05-31
    • 2010-11-30
    • 2017-02-07
    • 1970-01-01
    • 2013-08-16
    • 1970-01-01
    • 2019-02-27
    • 2019-07-05
    • 2016-11-25
    相关资源
    最近更新 更多