2013-08-31 98 views
-1

代碼:太多的孩子與叉()

for (ii = 0; ii < 24; ++ii) { 

    switch (fork()) { 

     case -1 : { 
       printf("\n\nproblem with fork() !!! \n\n"); 
       exit(0); 
       }; 

     case 0 : { 
       WriteOnShared_Mem(ii); 
       }break; 
     default : { 
       ChildPidTab[ii] = p; 
       usleep(50000); 
       ReadShared_MemMp(nbSect, 24,ChildPidTab); 
       }; 
    } 
} 

我的問題是,我得到了太多的孩子(nbenfant = 24),我得到的遠遠超過24:/

這是我的今天第3篇文章在這裏,但仍然沒有解決:(

感謝

+0

請在你的代碼(名稱,字符串,註釋)用英語 –

+2

請不要發佈兩次同樣的問題... – Xymostech

回答

1

仔細閱讀fork(2)手冊頁。多次閱讀該頁面,這很難理解。請閱讀fork (system call)processes (computing)上的Wikipage。

請理解 - 和這需要時間這fork是返回同時在成功兩次:在孩子

fork系統調用可能會失敗一次是在家長和一次(然後返回-1)原因有很多。在fork失敗時,請使用perror或其他方式顯示errno。你應該始終保持fork的結果。所以代碼

for (ii = 0; ii < 24; ++ii) { 
fflush(NULL); 
pid_t p = fork(); 
switch (p) { 
    case -1 : // fork failed 
      printf("\n\nproblem with fork() in pid %d error %s!!! \n\n", 
        (int) getpid(), strerror(errno)); 
      exit(EXIT_FAILURE); 
      break; 
    case 0: // child process 
      WriteOnShared_Mem(ii); 
      ii = MAX_INT; // to stop the for loop 
      break; 
    default: // parent process 
      ChildPidTab[ii] = p; 
      /// etc.... some synchronization is needed 
      break; 
    } 

尤其fork可能會失敗,因爲

EAGAIN fork() cannot allocate sufficient memory to copy the 
      parent's page tables and allocate a task structure for 
      the child. 
    EAGAIN It was not possible to create a new process because the 
      caller's RLIMIT_NPROC resource limit was encountered. To 
      exceed this limit, the process must have either the 
      CAP_SYS_ADMIN or the CAP_SYS_RESOURCE capability. 
    ENOMEM fork() failed to allocate the necessary kernel structures 
      because memory is tight. 

如果你希望能夠到餐桌的多個進程,嘗試:

  • 增加RLIMIT_NPROC資源限制setrlimit(2)(可能會調用系統設施,所以也看看/etc/pam.d/login

  • 降低fork-計劃所需的資源。特別是降低堆內存要求

  • 增加一些系統資源,如可能交換。你可以用一些臨時文件swapon進行測試。

由於Joachim Pileborg replied你應該避免分叉太多(分叉過程繼續循環,從而也再次分叉)。

不要忘記stdio例程被緩衝。適當地使用fflush(3)

我建議你閱讀Advanced Linux Programming這本書(可以在線獲得),它有一個完整的章節解釋Linux上的進程處理。

BTW,請與pstoppstree你有多少(並與free命令多少內存使用,但抱怨之前閱讀http://linuxatemyram.com/)的過程。也可能發生這樣的情況,即你的特定系統不能跨越你的特定程序超過24倍(因爲缺乏資源)

也研究簡單shell的源代碼(如sash)並使用strace -f(例如在某些shell ,或者在你的程序中)來更多地瞭解系統調用的完成情況。還要學習如何使用gdb調試器。

+0

我只是想我的24小孩,但他們需要運行在 – D3fman

+0

「分叉得太多」我怎麼做了一個叉子:( – D3fman

+0

好的謝謝你糾正的fork()錯誤,但我不能檢查它,因爲沒有錯誤時,我做叉() - _- – D3fman

1

這是因爲每個孩子繼續循環,所以反過來叉自己的孩子。當孩子們都做了,就應該把從返回主要功能或致電exit

+0

是問題是,我不能使用exit()bcz它會殺死孩子,我需要24個孩子同時運行:/那些r指令。 – D3fman

+1

@shubha'exit'調用只是退出當前*進程,而不是其父進程或兄弟進程。 –

+0

是的,如果我確實退出孩子會殺死他們,但我不希望我只想讓24個孩子同時跑步。那可能嗎 ? – D3fman

1

子進程coutinue fork新的子進程,你只需要停止它。

像這樣:

switch (fork()) { 

    case -1 : { 
      printf("\n\nproblem with fork() !!! \n\n"); 
      exit(0); 
      }; 

    case 0 : { 
      i = 24 ;     //--- here I set i = 24 , so child process will stop fork new child process. 
      WriteOnShared_Mem(ii); 
      }break; 
    default : { 
      ChildPidTab[ii] = p; 
      usleep(50000); 
      ReadShared_MemMp(nbSect, 24,ChildPidTab); 
      }; 
    } 
} 
+0

好吧,如果我喜歡你說的話,我只有一個孩子?不是? – D3fman

+0

不,你不明白'fork'是如何工作的,或者你對純C *編程太新手了。 –

+0

我是一個新手,我剛剛開始去年:) – D3fman