0

我正在用 C 语言做一个客户端-服务器应用程序来模拟纸牌游戏。这是一个一对一的游戏,客户端在线程工作者(每场比赛一个工作者)的协助下玩游戏。我试图做一些测试,但在某些时候,服务器完全没有理由崩溃了。该代码充满了检查以尝试以各种方式安全地结束它。发布所有代码是不可想象的,但这是计算的结果(我已经重复了超过 10 次获得相同的结果):

worker: Start Playing!
worker: hand number: 0
worker: player pluto playing on port 6!
Killed

任何可能的原因?其他人遇到同样的问题?

4

2 回答 2

2

当您的程序kill -9来自其他程序或脚本时,就会发生这种情况。

一种常见的神秘进程杀手是 Linux内存不足 (OOM) 杀手。在 Linux 下,当程序分配太多内存时,您不会从 NULL 中返回 NULL malloc(),也不会从操作员那里得到异常new。相反,您的程序可能会被kill -9内核'd'。

OOM 杀手

Linux 有一个奇怪的(但明智的)策略,它允许进程根据需要分配尽可能多的内存,即使没有足够的内存来满足请求。这是因为许多程序会乐观地分配大量内存,但实际上并未使用所有这些内存。Linux 允许程序分配它们想要的任何东西,并且只有当它们尝试访问该内存时,Linux 才会检查该内存是否存在。

如果没有,内核就处于绑定状态,因为它告诉程序内存可用(即malloc()之前返回了一个有效指针),现在它被骗了。没有好的方法可以向程序发出错误信号,哎呀,我犯了一个错误,我应该早点返回 NULL。

这就是OOM杀手发挥作用的地方。OOM杀手就像一家航空公司超额预订了航班,现在必须说服付费客户不要乘坐该航班。我知道你付了钱,但也许有人会好心搭晚一点的航班?

内核不能满足内存请求,怎么办?它可以说“对不起,我撒谎了”并终止当前程序。或者它可以杀死其他程序以释放内存,直到当前程序有足够的空闲空间。OOM 杀手试图充分利用糟糕的情况。它试图找出最好的杀死程序是什么,以尽量减少损害。如果有一些新启动的程序正在消耗大量内存,那就是它会杀死的人。这是有道理的。程序很有可能有一个错误,导致它分配了太多的内存。

或者考虑另一种可能性:您的程序完全是无辜的,但是其他一些程序行为不端,OOM 杀手决定杀死的程序。

我不知道这是否正在发生。但是当我听到“我的程序被无缘无故地杀死”时,我认为是OOM杀手,因为我以前被这个混蛋烧过。

于 2012-10-13T15:18:49.983 回答
0

“Killed”是您的程序收到时打印的消息SIGKILLSIGKILL不可捕获或可屏蔽,这意味着它保证会杀死您的程序(SIGKILL通常是信号 9,导致常见的习惯用法kill -9 <pid>是杀死一个进程)。

如果你没有在kill -9某个地方触发,那么可能的罪魁祸首就是 OOM 杀手。@JohnKugelman 很好地概述了凶手。

您可以通过查看来确定 OOM 杀手是否杀死了您的进程/var/log/messages

grep -i 'killed process' /var/log/messages
于 2012-10-13T15:24:21.993 回答