通过共享库控制进程分叉

Control process forking via shared library

我正在做一个实验项目(只是为了好玩),我需要一种方法来控制我的进程分叉的“节奏”。基本上,我有一个程序可以在不附加到其子项的情况下自行分叉。子进程通过 execl.

引导相同的程序
// other includes
#include "hook.h"

int
main()
{
  const char* progname = "main";
  unsigned int child_i;
  pid_t pid;

  for (child_i = 0; child_i < 3; child_i++)
    {
      // Does some irrelevant stuff here
      hook_take();
      pid = fork();
      if (pid == 0)
        {
          execl(progname, progname, NULL);
        }
      else
        {
          hook_free();
        }

    }

  return 0;
}

这里的想法是创建一个流程树,如下所示:

main
  |-p0
  |  |-p00
  |  |  |-p001
  |  |  |-p002
  |  |  |-p003
  |  |-p01
  |  |  |-p011
  |  |  |-p012
  |  |  |-p013
  |  |-p02
  |  |  |-p021
  |  |  |-p022
  |  |  |-p023
  |-p1
  |  |-p10
  |  |  |-p101
  |  |  |-p102
  |  |  |-p103
  |  |-p11
...

然而,这最终会创建过多的进程并且系统变得不稳定。这就是为什么我选择使用共享库 (hook.h) 在达到最大进程数时阻止进程。这是 hook_take()hook_free() 的工作。它们在单独的 hook.h 文件中定义。

#ifndef HOOK_H
#define HOOK_H


#ifdef __cplusplus
extern "C"
{
#endif

  #define MAX_HOOKS 1000
  extern unsigned int _hooks_count;

  void hook_take();
  void hook_free();

#ifdef __cplusplus
}
#endif

#endif /* HOOK_H */

并在 hook.c 中实施。

#include "hook.h"

#include <unistd.h>

unsigned int _hooks_count = 0;

void
hook_take()
{
  while (_hooks_count == MAX_HOOKS)
    {
      sleep(1);
    }
  _hooks_count++;
}

void
hook_free()
{
  if (_hooks_count > 0)
    {
      _hooks_count--;
    }
}

hook.c编译为共享库并动态链接到主程序

经过一些研究,我很快意识到这是行不通的。因为每个进程都会创建自己的变量副本 _hooks_count.

解决这个问题最简单又不麻烦的方法是什么?请记住,这只是一个实验项目,我的代码不需要企业级或任何东西。

在 Linux 上实现进程间信号量的方法有很多种。可以说 POSIX 信号量是最简单的:

#define SNAME "/tmp/hook_count"

// PLEASE CHECK ALL ERROR CODES !!!

// In root process
sem_t *sem = sem_open(SNAME, O_CREAT, 0644, MAX_HOOKS);

// In child process after fork
sem_t *sem = sem_open(SEM_NAME, 0);
sem_wait(sem);

// In child process before exit
sem_post(sem);