操作系统终止您的进程时返回代码

时间:2009-04-12 20:54:32

标签: linux memory-management process return-value kill

我想测试是否使用乘法进程我能够在32位O.S上使用超过4GB的ram(我的:Ubuntu,1GB内存)。

所以我编写了一个小程序,mallocs略小于1GB,并对该阵列执行一些操作,并运行该程序的5个实例查询分析。

问题是,我怀疑O.S杀了他们中的4人,只有一人幸免于难,并且显示出“PID:我已经完成了”。

(我已经尝试过使用小型数组并进行5次打印,当我查看使用TOP的运行进程时,我只看到一个实例..)

奇怪的是这个 - 我收到了所有实例中的返回码0(成功?),包括那些据称被O.S杀死的实例。

我没有得到任何按摩说明过程被杀死了。

此情况的返回码是否正常?

(如果是这样,它会降低我对'返回代码'的信任......)

感谢。

编辑:一些答案表明小程序中可能存在错误,所以就是这样。分叉和保存返回代码的较大程序较大,我在这里上传时遇到问题,但我认为(希望)没关系。

另外我注意到,如果不是用我的分叉程序运行它,我使用'./a.out& ./a.out& ./a.out& ./a.out& amp;' (当./a.out是附加的小程序的二进制文件时) 我确实看到了一些“被杀”的消息。

#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <unistd.h>
#define SMALL_SIZE 10000
#define BIG_SIZE 1000000000
#define SIZE BIG_SIZE
#define REAPETS 1

    int
main()
{
    pid_t my_pid = getpid();

    char * x = malloc(SIZE*sizeof(char));

    if (x == NULL)
    {
            printf("Malloc failed!");
            return(EXIT_FAILURE);
    }

    int x2=0;
    for(x2=0;x2<REAPETS;++x2)
    {
            int y;
            for(y=0;y<SIZE;++y)
                    x[y] = (y+my_pid)%256;
    }
    printf("%d: I'm over.\n",my_pid);
    return(EXIT_SUCCESS);
}

6 个答案:

答案 0 :(得分:5)

用什么信号来杀死进程?

0到127之间的退出代码(包括0和127)可以自由使用,128以上的代码表示进程被信号终止,退出代码为

128 +使用的信号数

答案 1 :(得分:5)

好吧,如果您的进程无法malloc() 1GB的内存,操作系统将不会终止进程。所有发生的事情是malloc()返回NULL。因此,根据您编写代码的方式,过程可能会返回0 - 如果您希望在内存分配失败时返回错误代码(这通常是一种很好的做法),您必须将该行为编入它

答案 2 :(得分:4)

流程的返回状态(由waitwaitpidsystem返回)包含或多或少的以下内容:

  • 退出代码,仅在流程正常终止时才适用
  • 是否发生正常/异常终止
  • 终止信号,仅适用于通过信号终止进程的情况

如果您的进程被OOM杀手杀死(显然会向您发送SIGKILL信号),退出代码完全没有意义

有关更多信息,请参阅wait命令的手册页。

答案 3 :(得分:3)

此代码显示如何获取孩子的终止状态:

#include <stdio.h>
#include <stdlib.h>

#include <unistd.h>
#include <sys/wait.h>

int
main (void)
{ 
  pid_t pid = fork();

  if (pid == -1)
  {
    perror("fork()");
  }
  /* parent */
  else if (pid > 0)
  {
    int status;

    printf("Child has pid %ld\n", (long)pid);

    if (wait(&status) == -1)
    {
      perror("wait()");
    }
    else
    {
      /* did the child terminate normally? */
      if(WIFEXITED(status))
      {
        printf("%ld exited with return code %d\n",
               (long)pid, WEXITSTATUS(status));
      }
      /* was the child terminated by a signal? */
      else if (WIFSIGNALED(status))
      {
        printf("%ld terminated because it didn't catch signal number %d\n",
               (long)pid, WTERMSIG(status));
      }
    }
  }
  /* child */
  else
  {
    sleep(10);
    exit(0);
  }

  return 0;
}

答案 4 :(得分:1)

您是否检查了fork()的返回值?如果fork()无法为新进程的地址空间分配足够的内存,则很有可能返回错误(-1)。调用fork()的典型方法是:

pid_t pid;
switch(pid = fork())
{
case 0:
    // I'm the child process
    break;
case -1:
    // Error -- check errno
    fprintf(stderr, "fork: %s\n", strerror(errno));
    break;
default:
    // I'm the parent process
}

答案 5 :(得分:1)

退出代码仅在WIFEXITED宏评估为true时才“有效”。请参阅man waitpid(2)

您可以使用WIFSIGNALED宏来查看您的程序是否已发出信号。