我一点也不熟悉C。
如何启动子进程?此子进程将通过调用 execve()
来执行指定的命令。它将尝试在环境变量中指定的文件目录中搜索PATH
命令可以作为可执行文件找到。
到目前为止,我已经这样做了:
//Do commands
pid_t childId;
// Fork the child process
child_id = safefork.c(); //can't use fork();
safefork.c
导师提供的代码;不要诅咒信使!
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#include <sys/errno.h>
extern int errno;
#define MAX_PROCESSES 6
static int n_processes(void)
{
return system("exit `/bin/ps | /store/bin/wc -l`")/256;
}
pid_t safefork(void)
{
static int n_initial = -1;
if (n_initial == -1) /* Første gang funksjonen kalles: */
n_initial = n_processes();
else if (n_processes() >= n_initial+MAX_PROCESSES) {
sleep(2);
errno = EAGAIN;
return (pid_t)-1;
}
return fork();
}
修复代码
在代码中,获取拼写一致的变量名称(child_id
与childId
不同(。
pid_t child_id = simplefork();
if (child_id < 0)
{
...handle error...
}
else if (child_id == 0)
{
...do childish code - execve() etc...
}
else
{
...do parental code - waitpid() etc...
}
请注意,simplefork()
函数中供你使用的fork()
调用负责创建新进程。 这就是它所需要的;这是除第一个流程之外的所有流程的处理方式。
为什么不fork()
?
"不能使用fork()
"是什么意思?主要的替代机制是 vfork()
,这是fork()
的一个非常有限的变体(不要使用它(;或者你可以使用posix_spawn()
或posix_spawnp()
——这是非常复杂的替代方案。我认为没有其他选择。
分叉后,您可以使用execvp()
而不是execve()
- 它将为您进行路径搜索。 当然,除非练习的目的是在execve()
方面实施execvp()
。
您的代码使用符号 safefork.c()
,但这在 C 中通常不正确;我可以设计一种结构类型来使其工作,但这可能不是你的意思。
我们得到了另一个名为
safefork.c
的文件 — 我们不允许使用fork
,只能使用已经给出的safefork
。
[...在代码发布之前]
好吧,这很好奇。据推测,您有一个标头safefork.h
,它声明了您应该使用的任何功能(可能是extern pid_t safefork(void);
(,并且文件safefork.c
它执行某些操作来包装fork()
。'这很奇怪:我不认为fork((是一个危险的函数。我很想知道"安全分叉"的作用,但我怀疑它是否比标准分叉功能安全得多。(我想它可以在调用 fork(( 之前做一些像 fflush(0( 这样的事情,或者在 fork(( 失败时执行错误退出,但这是在推动信封。
[...代码发布后]
对safefork()
代码的批评,我完全认识到这不是你自己的代码,而是给你使用的代码。
safefork()
的代码是可憎的。它通过 system()
运行一个 shell,该 shell 运行 ps
并wc
找出您当前正在运行的进程数,如果您无法执行fork()
,则进入睡眠状态 2 秒,因为正在运行的进程太多(超过 6 个,可能包括 safefork()
3 个正在运行的进程!(,然后返回"我失败了"。有人需要他们的头脑看到(不,那不是你;它是代码的作者(。
哦,extern int errno;
是不正确的;声明errno
的唯一安全方法是#include <errno.h>
。对老师的失误给予负面评分。#include <sys/errno.h>
不是一个好主意; 现代 POSIX 中通常不需要#include <sys/types.h>
——至少从 POSIX 2008 年开始;在此之前可能没有必要(。 在 safefork.h
标头的上下文中,使其自包含确实需要 #include <sys/types.h>
。
即使假设safefork()
是一个好主意(事实并非如此(,也应该按如下所示实现。
safefork.h
#ifndef SAFEFORK_H_INCLUDED
#define SAFEFORK_H_INCLUDED
#include <sys/types.h> // pid_t
extern pid_t safefork(void);
#endif
safefork.c
#include "safefork.h"
#include <errno.h>
#include <stdlib.h>
#include <unistd.h>
#define MAX_PROCESSES 6
static int n_processes(void)
{
return system("exit `/bin/ps | /store/bin/wc -l`") / 256;
}
pid_t safefork(void)
{
static int n_initial = -1;
if (n_initial == -1)
n_initial = n_processes();
else if (n_processes() >= n_initial+MAX_PROCESSES)
{
errno = EAGAIN;
return (pid_t)-1;
}
return fork();
}