提交 5b18633f 编写于 作者: W wizardforcel

2020-05-10 20:19:16

上级 24cb45d5
......@@ -4,13 +4,13 @@
## 一句警告
进程分叉是一个非常强大(非常危险)的工具。如果你陷入困境并造成一个叉炸弹(本页后面会有解释),**你可以关闭整个系统**。为了减少这种情况,可以通过在命令行中键入`ulimit -u 40`将最大进程数限制为较小的数量,例如 40。请注意,此限制仅适用于用户,这意味着如果您分叉炸弹,那么您将无法杀死刚刚创建的所有进程,因为调用`killall`需要 shell 来 fork()...具有讽刺意味的权利?那么我们可以做些什么呢。一种解决方案是在另一个用户(例如 root)之前生成另一个 shell 实例,然后从那里杀死进程。另一种方法是使用内置的`exec`命令来杀死所有用户进程(小心你只有一次射击)。最后你可以重启系统:)
进程分叉是一个非常强大(非常危险)的工具。如果你陷入困境并造成一个分叉炸弹(本页后面会有解释),**你可能关闭整个系统**。为了减少这种情况,可以通过在命令行中键入`ulimit -u 40`将最大进程数限制为较小的数量,例如 40。请注意,此限制仅适用于用户,这意味着如果您分叉了炸弹,那么您将无法杀死刚刚创建的所有进程,因为调用`killall`需要 shell 来 `fork()`...很讽刺对吗?那么我们可以做些什么呢。一种解决方案是在另一个用户(例如 root)之前生成另一个 shell 实例,然后从那里杀死进程。另一种方法是使用内置的`exec`命令来杀死所有用户进程(小心你只有一次机会)。最后你可以重启系统:)
在测试 fork()代码时,请确保您对所涉及的计算机具有 root 和/或物理访问权限。如果您必须远程处理 fork()代码,请记住 **kill -9 -1** 将在紧急情况下为您节省时间。
在测试`fork()`代码时,请确保您对所涉及的计算机具有 root 和/或物理访问权限。如果您必须远程处理`fork()`代码,请记住`kill -9 -1`将在紧急情况下为您节省时间。
TL; DR:如果您没有为此做好准备,那么**非常**会很危险。 **你被警告过了。**
太长不看:如果您没有为此做好准备,那么会**非常**危险。**警告过你了**
## 叉子介绍
## 分叉介绍
## fork 做什么?
......@@ -160,7 +160,7 @@ int main(int argc, char**argv) {
`system`调用将 fork,执行参数传递的命令,原始父进程将等待此操作完成。这也意味着`system`是一个阻塞调用:在`system`退出进程之前,父进程无法继续。这可能有用也可能没用。此外,`system`实际上创建了一个 shell,然后给出了字符串,这比直接使用`exec`更开销。标准 shell 将使用`PATH`环境变量来搜索与命令匹配的文件名。对于许多简单的 run-this-command 问题,使用系统通常就足够了,但很快就会成为更复杂或微妙问题的限制,它隐藏了 fork-exec-wait 模式的机制,所以我们鼓励你学习和使用`fork` `exec``waitpid`代替。
## 什么是最愚蠢的叉子例子?
## 什么是最愚蠢的分叉例子?
一个稍微愚蠢的例子如下所示。它会打印什么?尝试使用程序的多个参数。
......
......@@ -30,7 +30,7 @@ int main() {
* execl:用/ bin / ls 替换程序映像并调用其 main()方法
* perror:我们不希望到达这里 - 如果我们这样做,那么 exec 就失败了。
## 微妙的叉子
## 微妙的分叉
这段代码出了什么问题
......
......@@ -47,7 +47,7 @@
## 餐饮哲学家
Dining Philosophers 问题是一个经典的同步问题。想象一下,我邀请 N(让我们说 5 位)哲学家吃饭。我们将坐在一张桌子上,用五根筷子(每个哲学家之间一个)。哲学家在想要吃饭或思考之间交替。吃饭的哲学家必须在他们的位置两侧拾起两根筷子(原始问题要求每个哲学家都有两把叉子)。然而,这些筷子与他的邻居分享。
Dining Philosophers 问题是一个经典的同步问题。想象一下,我邀请 N(让我们说 5 位)哲学家吃饭。我们将坐在一张桌子上,用五根筷子(每个哲学家之间一个)。哲学家在想要吃饭或思考之间交替。吃饭的哲学家必须在他们的位置两侧拾起两根筷子(原始问题要求每个哲学家都有两把分叉)。然而,这些筷子与他的邻居分享。
![5DiningPhilosophers](img/faa7ac1f5f07a2ceee3dcc5057f329c6.jpg)
......
......@@ -71,14 +71,14 @@ void* philosopher(void* forks){
这可以防止死锁,因为没有循环等待!没有哲学家必须等待任何其他哲学家。
高级仲裁者解决方案是实施一个类,确定哲学家的分叉是否在仲裁员的掌握之中。如果他们是,他们把它们交给哲学家,让他吃,并把叉子拿回来。这有额外的好处,可以让多个哲学家同时吃。
高级仲裁者解决方案是实施一个类,确定哲学家的分叉是否在仲裁员的掌握之中。如果他们是,他们把它们交给哲学家,让他吃,并把分叉拿回来。这有额外的好处,可以让多个哲学家同时吃。
### 问题:
* 这些解决方案很慢
* 他们有一个单点的失败,仲裁员使其成为瓶颈
* 仲裁者也需要公平,并能够在第二个解决方案中确定死锁
* 在实际系统中,仲裁员倾向于将重复的叉子交给那些因为过程调度而吃的哲学家
* 在实际系统中,仲裁员倾向于将重复的分叉交给那些因为过程调度而吃的哲学家
## 离开桌子(Stallings 的解决方案)
......@@ -96,7 +96,7 @@ void* philosopher(void* forks){
这是 Dijkstra 的解决方案(他是在考试中提出这个问题的人)。为什么第一个解决方案陷入僵局? Dijkstra 认为最后一个拿起左叉的哲学家(使解决方案陷入僵局)应该选择他的权利。他用数字 1..n 来完成它,并告诉每个哲学家拿起他的较低数字叉。
让我们再次遇到死锁情况。每个人都试图先拿起他们的低号码叉。哲学家 1 获得分叉 1,哲学家 2 获得分叉 2,依此类推,直到我们到达哲学家 n。他们必须在 fork 1 和 n 之间进行选择。 fork 1 已被哲学家 1 所阻挡,所以他们无法拿起那个叉子,这意味着他不会拿起叉子。我们已经打破了循环等待!意味着死锁是不可能的。
让我们再次遇到死锁情况。每个人都试图先拿起他们的低号码叉。哲学家 1 获得分叉 1,哲学家 2 获得分叉 2,依此类推,直到我们到达哲学家 n。他们必须在 fork 1 和 n 之间进行选择。 fork 1 已被哲学家 1 所阻挡,所以他们无法拿起那个分叉,这意味着他不会拿起分叉。我们已经打破了循环等待!意味着死锁是不可能的。
### Problems:
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册