2

乗算プロセスを使用して、32ビットOSで4GBを超えるRAMを使用できるかどうかをテストしたかった(私の場合:1GB RAMのUbuntu)。

そのため、1GB よりわずかに小さいサイズを malloc する小さなプログラムを作成し、その配列に対して何らかのアクションを実行し、このプログラムの 5 つのインスタンスを fork で実行しました。

問題は、OSがそれらのうち4つを殺し、1つだけが生き残り、「PID:終了しました」と表示したと思われることです)。

(小さな配列で試してみたところ、5つの印刷がありました.TOPで実行中のプロセスを見ると、インスタンスが1つしか表示されません..)

奇妙なことはこれです-OSによって殺されたとされるものを含む、すべてのインスタンスでリターンコード0(成功?)を受け取りました

プロセスが強制終了されたことを示すメッセージは表示されませんでした。

この戻りコードは、この状況では正常ですか?

(そうであれば、「リターンコード」に対する私の信頼が低下します...)

ありがとう。

編集:いくつかの回答は、小さなプログラムで発生する可能性のあるエラーを示唆していたので、ここにあります。リターン コードをフォークして保存するより大きなプログラムはより大きく、ここにアップロードするのは難しいですが、問題ないと思います (そして希望します)。

また、fork プログラムで実行する代わりに、'./a.out & ./a.out & ./a.out & ./a.out &' を使用して端末で実行すると ( ./a.out は、添付された小さなプログラムのバイナリです) 'Killed' メッセージがいくつか表示されます。

#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);
}
4

6 に答える 6

5

プロセスを強制終了するために使用されたシグナルは何ですか?

0 から 127 までの終了コードは自由に使用できます。128 を超えるコードは、プロセスがシグナルによって終了したことを示します。終了コードは次のとおりです。

128 + 使用する信号の数

于 2009-04-12T21:07:11.067 に答える
5

malloc()プロセスが1GB のメモリを使用できない場合、OS はプロセスを強制終了しません。NULLをmalloc()返すだけです。したがって、コードの書き方によっては、プロセスがとにかく 0 を返す可能性があります。メモリ割り当てが失敗したときにエラー コードを返すようにしたい場合 (これは一般的に良い方法です)、その動作を次のようにプログラムする必要があります。それ。

于 2009-04-12T21:07:43.047 に答える
4

プロセスの戻りステータス ( waitwaitpidおよびによって返されるsystem) には、多かれ少なかれ次のものが含まれます。

  • 終了コード。プロセスが正常に終了した場合にのみ適用されます
  • 正常/異常終了の有無
  • 終了シグナル。プロセスがシグナルによって終了した場合にのみ適用されます

プロセスが OOM キラーによって強制終了された場合、終了コードはまったく意味がありません (明らかに SIGKILL シグナルが送信されます)。

詳細については、waitコマンドのマニュアル ページを参照してください。

于 2009-04-12T21:14:29.723 に答える
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;
}
于 2009-04-14T14:22:30.087 に答える
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
}
于 2009-04-12T21:15:02.670 に答える