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