C fork()反复失败

C fork()反复失败,c,fork,zos,C,Fork,Zos,我试图使用fork创建一个子进程,但它反复返回-1,我试图找到原因,结果是: Fork() will fail and no child process will be created if: [EAGAIN] The system-imposed limit on the total number of pro- cesses under execution would be exceeded. This limit

我试图使用
fork
创建一个子进程,但它反复返回-1,我试图找到原因,结果是:

Fork() will fail and no child process will be created if:
[EAGAIN]           The system-imposed limit on the total number of pro-
                   cesses under execution would be exceeded.  This limit
                   is configuration-dependent.

[EAGAIN]           The system-imposed limit MAXUPRC (<sys/param.h>) on the
                   total number of processes under execution by a single
                   user would be exceeded.

[ENOMEM]           There is insufficient swap space for the new process. 
这里提到了CHILD_MAX:

上面的代码运行良好,并在我自己的笔记本电脑(centos)上创建了一个子进程,但在开发环境中,我想有一些限制


调用\u child永远不会被调用,因为返回的
prc\u id
为-1(甚至在进入函数时也不会打印第一条print语句)。

如果您一直在玩
fork
(2)您可能已经用完了进程可用的进程限制,请参阅shell的
ulimit

$ help ulimit | grep process
Ulimit provides control over the resources available to processes
    -d      the maximum size of a process's data segment
    -l      the maximum size a process may lock into memory
    -u      the maximum number of user processes

如果是这样,注销并再次登录将解决问题

我将您的示例程序复制到运行z/OS 2.3版的z/OS系统中,但有一个小小的增强,因为您省略了调用_child函数(更新后为SC_MAX_child添加sysconf()值):

很可能您的构建或执行环境配置不正确。它在我相当基本的系统上绝对可以正常工作,而且我根本不需要做任何不寻常的事情来让它运行

一些小提示

您是如何进入z/OS UNIX shell的?如果您登录到TSO,然后运行ISPFShell或OMVS命令,您可能更喜欢简单地将SSH’ing连接到z/OS系统中。我通常发现这是最干净的批处理环境

第二件事是,您可能希望仔细检查您的C/C++环境。IBM XLC编译器内置了一些很好的调试功能—请尝试
man C99
(或您使用的任何方言)并阅读

第三件事是IBM在z/OS中包含了dbx调试器,所以如果您真的陷入困境,只需尝试在dbx下运行可执行文件,就可以一次一步地完成程序行

至于那些错误等等,别忘了也看看
\uu errno2()
值——它们通常有一个非常特定的原因码,与更一般的错误一起出现。例如,您的z/OS安全管理员当然可以限制您对z/OS UNIX功能的使用,这将在
\uu errno2()
值中清楚地显示出来


不过要坚持下去——如果您了解UNIX或Linux,那么如果您花一点时间学习基础知识,从使用shell到编写代码的所有技能几乎都会100%转移到z/OS

我认为它不能在Z上运行/OS@Joshua,他可能还有一个进程。在shell中,调用编译器使用该进程。好的。然后他运行他的程序,他也可以启动,就像他可以启动编译器一样。然后它调用fork(2),并失败。@AgrudgeAmicus,IBM似乎认为z/OS有fork:。如果不是,他的系统严重错误地配置了头文件和库,用于不受支持的系统调用。@JamesK.Lowden system在当前运行的某些文件中有
fork
——我认为您关于2个进程的观点是正确的,我的想法有些相同。但是还有一个文件使用了
fork
pthreads
——我想线程系统会有所不同。@JamesK.Lowden:不
cc
调用
ld
。他们至少要编译两个。请进入
sys1.sceeh.sys.h
并检查为
\u SC\u CHILD\u MAX
设置了什么值。我相信您可能误解了\u SC\u CHILD\u MAX的用法。在unix shell中(准确地说是在/etc/profile中)->行
中为\u C89\u CC\u CXX中的\u CMP设置了一个大问题;do
已注释,我没有取消注释的编辑权限,因此在编译文件时,我获得了
IKJ56228I数据集CEE.SCEELKEX不在目录中或目录无法访问
错误&我无法在unix环境中测试。虽然MAXPROCSYS是4096,MAXPROCUSER是2048,但还有其他值:
sysconf(\u SC\u MAX\u CHILD)
->-1,
errno-->a0000 errno2-->c10f0001
------这是在非unix环境中运行代码的时候。浏览IBM的“z/OS unix服务消息和代码”可以发现“a000”没有错误c10f0001没有错误2,所以这里有一些更戏剧性的事情发生。还有一些其他的观点可能会对你有所帮助。首先,所有errno/errno2值都在一本名为“z/OS UNIX系统服务:消息和代码”的书中定义。如果在遇到问题后立即使用“printf(“Error%x/%x-%s”、errno、_errno2()、strerror(errno))”或类似的命令(请记住,许多库函数都会重置errno,因此在出现错误时需要立即引用它),那么您的运气会更好。另外,因为我提到的文档以十六进制列出了errno,所以通常最好使用“%x”打印它们。进程限制是并发运行的进程,而不是累积值。“ps”命令告诉您正在运行什么,我从未见过z/OS系统配置的进程/用户少于25个。该设置来自UNIX服务配置文件,类似于SYS1.PARMLIB(BPXPRM00)。在这里,MAXPROCSYS(全系统进程限制)和MAXPROCUSER(每个用户的最大进程数)是关键。如果需要,还可以逐个用户覆盖这些值。如果您可以访问z/OS操作员控制台,“D OMVS,LIMITS”命令将告诉您当前设置。
//<unistd.h> - DEFINED IN MY SYSTEM
#define _SC_CHILD_MAX            2 
  #include<stdio.h>
  #include<errno.h>
  #include<unistd.h>
  #include<stdlib.h>

   int main()
   {
       long int prc_id;

       prc_id=fork();

       if(prc_id ==0)
          calling_child();        
       else if(prc_id <0)
       {
           printf("errno - %d\n",errno); 
           printf("failed %d\n",prc_id);
           exit(0);
       }

      return 0;
 }
$ help ulimit | grep process
Ulimit provides control over the resources available to processes
    -d      the maximum size of a process's data segment
    -l      the maximum size a process may lock into memory
    -u      the maximum number of user processes
  #include<stdio.h>
  #include<errno.h>
  #include<unistd.h>
  #include<stdlib.h>

   int main()
   {
       long int prc_id;
       printf("SC_CHILD_MAX = %d\n", sysconf(_SC_CHILD_MAX));

       prc_id=fork();

       if(prc_id ==0)
          calling_child();        
       else if(prc_id <0)
       {
           printf("errno - %d\n",errno); 
           printf("failed %d\n",prc_id);
           exit(0);
       }

      return 0;
     } 

   static void calling_child(void)
   {
      printf("Hello from PID %x\n", getpid());
      return;
   }
SC_CHILD_MAX = 32767
Hello from PID 40100b2