c - 为 pthread 分配内存,然后 fork + execvp

标签 c memory-management pthreads exec fork

我收到一个事件,并根据该事件进行一些处理,然后 fork + execvp 一些其他程序(称为 some_jazzy_program)。最初我使用了 while 循环,其中执行了以下操作:

 while (some condition)
 {
      pid = fork();

      if (pid == 0)
      {
            do_some_work()

            execvp (some_jazzy_program..);
      }
      else 
      {
            do_some_bookkeeping();
      }
 }

这种设计的问题是,如果 do_some_work() 占用大量时间,那么我无法足够快地生成新进程来启动 some_jazzy_program。为了解决这个问题,我开始使用 pthreads:

  pthread_t *work_threads[MAX_FORKS_ALLOWED];

  while (some condition)
  {
      work_threads[index] = (pthread_t *) malloc (sizeof (pthread_t));

      pthread_create(work_threads[index], NULL, do_some_good_work, NULL);

      index ++;
  }

  void * do_some_good_work (void *arg)
  {
      pid = fork();

      if (pid == 0)
      {
            do_some_work()

            execvp (some_jazzy_program..);
      }
      else 
      {
            do_some_bookkeeping();
      }
 }  

这个设计有效。不过,我有几个问题。

调用 fork + excvp 来生成一个新进程。我应该在父程序中的哪里调用 pthread_exit() 。无论我读过什么,我都不一定需要调用 pthread_exit,因为当它要完成的工作完成时,线程会自动终止。在这种情况下,一旦我执行 fork + execvp 它就会死掉。

我的另一个担忧是关于work_threads[index] = (pthread_t *) malloc (sizeof (pthread_t))——我正在做的内存malloc。当我使用 malloc 时,我从堆中分配内存。我在哪里可以释放该内存并将其释放回堆。对我来说,不做任何事情看起来就像是内存泄漏。

我在这里尝试的通常是这样做的——首先运行多个 pthreads,然后在每个 pthread 中执行 fork + execvp

最佳答案

关于你的第一个问题,你不需要调用pthread_exit。如果您的主程序想要跟踪线程,您可以使用 pthread_join 并检查线程的返回状态。

关于你的第二个问题,你可以通过使用来避免堆内存分配:
pthread_t work_threads[MAX_FORKS_ALLOWED];

关于你的第三个问题,正如 Joachim 所说,在线程内 fork 并不常见;事实上也有点危险。 Think before you mix them

关于c - 为 pthread 分配内存,然后 fork + execvp,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25865724/

相关文章:

c - SDL2在C中转换SDL1.2代码,如何滚动窗口,以前的SDL_BlitSurface

c++ - 如何在 C 中访问 SOAP header

Java 文档和注释的 Java 内存管理

c++ - 有没有像 "pthread_getcancelstate"这样的函数?

c - return 0 是退出程序还是退出循环?

c - 可变长度消息数据的队列缓冲区的种类

java - 线程和方法调用如何在 Java 中的堆栈上分配?

javascript - 如何解释 Chrome 的内存分析结果?

c - 来自信号处理程序的 pthread_join

c - `pthread_join` 可能失败/未被调用并导致僵尸线程的情况