2013-08-31 65 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