2009-04-12 121 views
2

我想測試是否使用乘法進程我可以在32位O.S上使用超過4GB的RAM(我的Ubuntu:1GB RAM)。當操作系統殺死你的進程時返回代碼

所以我寫了一個小程序malloc稍小於1GB,並對該數組做一些操作,並運行該程序的5個實例vie叉。

事情是,我懷疑O.S殺死了其中4人,只有一人倖存並顯示它是「PID:我完成了」)。

(我有小陣試了一下,有5印刷,還當我看與TOP正在運行的進程,我看到的只有一個實例。)

奇怪的是這個 - 我在所有的實例中收到了返回代碼0(成功?),包括據稱被操作系統殺死的代碼

我沒有得到任何按摩說明進程被殺害。

這種情況的返回碼是否正常?

(如果是這樣,它減少了在 '返回代碼' ......我的事)

感謝。

編輯:一些答案在小程序中提出了可能的錯誤,所以在這裏。分支和保存返回代碼的較大程序比較大,而且我在這裏無法上傳,但我認爲(並且希望)它沒有問題。

而且我注意到,如果不是我的分岔程序運行它,我用終端運行」 ./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

的方法返回狀態(如由waitwaitpidsystem返回)包含更多或更少的以下內容:

  • 退出代碼,僅當處理正常終止
  • 正常/異常終止是否發生適用
  • 終止信號,僅當過程被信號

退出代碼終止適用如果您的進程被OOM殺手(顯然會向您發送SIGKILL信號)殺死的話,這完全沒有意義。

有關更多信息,請參閱wait命令的手冊頁。

5

什麼信號被用來殺死進程? 0和127之間

退出代碼,包容,可自由地使用,並且上述128碼指示該過程是由一個信號,其中,所述退出代碼是

+使用

128的信號的數目終止

+0

......希望我能給予好評的意見:) – 2009-04-12 21:40:33

5

那麼,如果你的進程無法malloc()這個1GB的內存,操作系統將不會殺死這個進程。發生的只是malloc()返回NULL。因此,根據您編寫代碼的方式,有可能過程可能返回0 - 如果您希望在內存分配失敗時返回錯誤代碼(這通常是很好的做法),您必須將該行爲編程爲它。

+0

並非完全如此。 Linux會讓進程過度分配內存,然後在實際使用內存過多時終止進程。 – 2009-04-12 22:13:12

+0

有趣的是,這是我聽到的第一個... – 2009-04-13 00:43:45

+0

但這仍然是猜測,唯一的方法是使用像Hasturkun提到的等待系統調用之一,並檢查狀態以及返回代碼。 – lothar 2009-04-13 00:47:55

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 
} 
1

退出代碼僅僅是「有效的」 WIFEXITED宏計算結果爲真時。man waitpid(2)

您可以使用WIFSIGNALED宏來查看您的程序是否已被髮送信號。

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; 
}