需要在SIGCHLD处理程序期间从子级访问变量

需要在SIGCHLD处理程序期间从子级访问变量,c,signals,parent-child,C,Signals,Parent Child,我在前面说这是一个家庭作业,我在写SIGCHLD处理程序时被卡住了。我需要访问子进程中的变量 #include <stdlib.h> #include <stdio.h> #include <signal.h> #include <unistd.h> #include <sys/types.h> #include <sys/wait.h> #define TEXT_LEN 10 #define NUM_RESCUE_PL

我在前面说这是一个家庭作业,我在写SIGCHLD处理程序时被卡住了。我需要访问子进程中的变量

#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


#define TEXT_LEN 10
#define NUM_RESCUE_PLOWS 4
#define NUM_VICTIMS_TO_RESCUE 40


/*  PURPOSE:  To keep trap of the number of victims that have been rescued.
 */
int numRescuedVictims = 0;



/*  PURPOSE:  To keep track of the process id's of the rescuing snow plows.
 */
pid_t plowPid[NUM_RESCUE_PLOWS];


/*  PURPOSE:  To note that at least one child plow has finished.  Reports the
 *process id and the number of victims rescued for each child plow.
 *'sigNum' tells the signal number.  No return value
 */
//  You may want to define a SIGCHLD listener here
//  It should have a loop that wait()s for children and
//  and prints how many victims each has rescued.
void listenSIGCHLD(int sig)
{
  int status;
  pid_t pidWait;
  while((pidWait = wait(&status)) > 0)
    printf("Plow %d rescued %d victim(s)", plowId, numVictimsRescued);
}


/*  PURPOSE:  To handle being informed of a rescued victim.  'sigNum' tells
 *signal number.  No return value.
 */
//  You may want to define a SIGUSR1 listener here
//  It increments 'numRescuedVictims' and prints the total number rescued victims
void listenSIGUSR1(int sig)
{
  numRescuedVictims += &numVictimsRescued;
  printf("We've rescued %d victims!" numRescuedVictims);
}


/*  PURPOSE:  To make 'NUM_RESCUE_PLOWS' processes to run 'rescuingPlow' to
 *rescue stuck victims, and then tell them to quit after all
 *'NUM_VICTIMS_TO_RESCUE' victims have been rescued.  Ignores parameters.
 *Returns 'EXIT_SUCCESS' to OS.
 */
int main ()
{

  //  I.  Applicability validity check:


  //  II.  Rescue victims:

  //  II.A.  Install 'SIGUSR1' handler:
  signal(SIGUSR1, listenSIGUSR1);

  // Install 'SIGUSR1' handler
  //  Install your SIGCHLD handler here
  signal(SIGCHLD, listenSIGCHLD);

  //  II.B.  Tell NUM_RESCUE_PLOWS plows to start rescuing the victims:

  int i;
  int myPid= getpid();

  for  (i = 0;  i < NUM_RESCUE_PLOWS;  i++)
    {
      //  Do a fork() and save it in plowPid[i]
      plowPid[i] = fork();
      //  If plowPid[i] is less than 0 then do:
      if(plowPid[i] < 0)
    {
      fprintf(stderr,"Dude, your system is WAY to busy to play rescuer!\n");
      return(EXIT_FAILURE);
    }

      //  If plowPid[i] is equal to 0 then do:
      else if(plowPid[i] == 0)
    {
      char pidText[TEXT_LEN];
      char indexText[TEXT_LEN];
    }
      snprintf(pidText,TEXT_LEN,"%d",myPid);
      snprintf(indexText,TEXT_LEN,"%d",i);
      execl("./rescuingPlow","rescuingPlow",pidText,indexText,NULL);
      fprintf(stderr,"Dude, somebody stole my plow!!\n");
      return(EXIT_FAILURE);
    }


  //  II.C.  Wait until all victims have been rescued:

  while  (numRescuedVictims < NUM_VICTIMS_TO_RESCUE)
    {
      sleep(1);
      printf("Searching for victims . . .\n");
    }


  //  III.  Finished:

  //  Loop to send SIGTERM to all NUM_RESCUE_PLOWS plow processes
  for (int i = 0; i < NUM_RESCUE_PLOWS; i++)
    {
      kill(plowPid[i], SIGTERM);
    }
  int toSleep= NUM_RESCUE_PLOWS;

  //  sleep() can be interrupted by SIGCHLD.  Whenever it is interrupted
  //  it returns the number of seconds that still remain on its alarm
  //  clock.  Let's wait until it has slept its full amount incase it
  //  was prematured interrupted by SIGCHLD.
  do
    {
      toSleep= sleep(toSleep);
    }
  while  (toSleep > 0);

  printf("Ready for the NEXT snow storm!\n");
  return(EXIT_SUCCESS);
}
#包括
#包括
#包括
#包括
#包括
#包括
#定义文本10
#定义数量4个救援犁
#定义受害者人数至救援人数40
/*目的:记录获救的受害者人数。
*/
int numRescuedVictims=0;
/*目的:跟踪救援雪犁的过程id。
*/
pid_t plowPid[NUM_RESCUE_PLOWS];
/*目的:注意至少有一个儿童犁已经完成。报告
*每个儿童犁的过程id和获救的受害者数量。
*“sigNum”表示信号号。无返回值
*/
//您可能需要在此处定义SIGCHLD侦听器
//它应该有一个循环来等待子对象和
//并打印出每个人救了多少受害者。
无效列表GCHLD(int sig)
{
智力状态;
等待;
while((pidWait=wait(&status))>0)
printf(“犁头%d救出%d名受害者)”,犁头ID,numvictimsrescused;
}
/*目的:处理获救受害者的通知。”符号
*信号号码。没有返回值。
*/
//您可能需要在此处定义SIGUSR1侦听器
//它增加“numRescuedVictims”并打印获救的受害者总数
无效列表GUSR1(内部信号)
{
numRescuedVictims+=&numVictimsRescued;
printf(“我们已经营救了%d名受害者!”numRescuedVictims);
}
/*目的:使“NUM_RESCUE_PLOWS”进程运行“RescuingFlow”以
*营救被困的受害者,然后告诉他们退出
*“NUM_受害者到_救援”受害者已获救。忽略参数。
*将“退出成功”返回到操作系统。
*/
int main()
{
//一、适用性有效性检查:
//二、救助灾民:
//II.A.安装“SIGUSR1”处理程序:
信号(SIGUSR1,listenSIGUSR1);
//安装“SIGUSR1”处理程序
//在此处安装SIGCHLD处理程序
信号(SIGCHLD,listenSIGCHLD);
//II.B.告诉NUM_RESCUE_PLOWS开始救援受害者:
int i;
int myPid=getpid();
对于(i=0;i0);
printf(“为下一场暴风雪做好准备!\n”);
返回(退出成功);
}
`

这就是最终生成的进程。虽然我还没有解决这个问题

/*
 *  rescuingPlow.c
 *
 *  Compile with $ gcc rescuingPlow.c -o rescuingPlow
 */
#include <stdlib.h>
#include <stdio.h>
#include <signal.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>


/*  PURPOSE:  To keep track of the number of victims that this process
 *  rescued.
 */
int numVictimsRescued   = 0;



/*  PURPOSE:  To return the number of victims rescued to the OS.  'sigNum'
 *  tells the signal number.  No return value.
 */
//  You may want to write a SIGTERM handling function
//  that returns to the OS 'numVictimsRescued'.



/*  PURPOSE:  To rescue victims at random intervals and inform parent process
 *  by sending it SIGUSR1 until receiving SIGTERM.  First parameter (after
 *  program name) tells parent's process id.  Second parameter tells this
 *  plow's index.
 */
int main    (int argc, char* argv[])
{

  //  I.  Applicability validity check:

  pid_t parentPID;
  int   plowId;

  if  (argc < 3)
  {
    fprintf(stderr,"USAGE: rescuingPlow <parentPID> <plowId>\n");
    return(EXIT_FAILURE);
  }

  parentPID = atoi(argv[1]);
  plowId    = atoi(argv[2]);


  //  II.  Rescuing victims until told to stop:

  //  II.A.  Install signal handler:

  //  Install your SIGTERM handler here
  srand(plowId);  //  Uniquely initialize random number generator so they act independently of each other


  //  II.B.  Rescue victims:

  //  Write an endless loop that:
  //  (1) Does 'sleep((rand() % 6) + 1);'
  //  (2) Increments 'numVictimsRescued'
  //  (3) Does 'printf("Plow %d rescued %d victim(s)!\n",plowId,numVictimsRescued);'
  //  (4) Send 'SIGUSR1' to 'parentPID'


  //  III.  Finished:

  return(EXIT_SUCCESS);
}
/*
*救援流量
*
*使用$gcc rescuingPlow.c编译-o rescuingPlow
*/
#包括
#包括
#包括
#包括
#包括
#包括
/*目的:跟踪在这一过程中受害的人数
*获救。
*/
int numVictimsRescued=0;
/*目的:将获救的受害者人数返回操作系统。”符号'
*告诉信号号码。没有返回值。
*/
//您可能需要编写一个SIGTERM处理函数
//这将返回到操作系统“numvictimsrescused”。
/*目的:以随机间隔营救受害者,并通知家长流程
*通过发送SIGUSR1直到收到SIGTERM。第一个参数(后
*程序名)告诉父进程id。第二个参数告诉
*普劳尔指数。
*/
int main(int argc,char*argv[])
{
//一、适用性有效性检查:
pid_t parentPID;
int-plowId;
如果(argc<3)
{
fprintf(stderr,“用法:rescuingflow\n”);
返回(退出失败);
}
parentPID=atoi(argv[1]);
plowId=atoi(argv[2]);
//II.在被告知停止之前抢救受害者:
//II.A.安装信号处理器:
//在此处安装SIGTERM处理程序
srand(plowId);//唯一地初始化随机数生成器,使它们相互独立
//II.B.救援受害者:
//写一个无休止的循环:
//(1)“睡眠((rand()%6)+1);”
//(2)增加“numviticimsrescreed”
//(3)是否有“printf”(“犁出%d个获救的%d个受害者!”\n),犁出ID,numVictimsRescued);'
//(4)将“SIGUSR1”发送到“parentPID”
//三、完成:
返回(退出成功);
}

我不完全确定我将如何处理这件事或如何处理这件事。我很有信心我可以处理存在的大多数其他问题。

如果不使用某些IPC机制,子进程只能将8位的值传递给父进程

这8位由子级作为参数发送给对
exit()
的调用,并由父级通过将宏
WEXITSTATUS()
应用于成功调用
wait()
waitpid()
返回的
status的值来接收。有关详细信息,请参见
man 2退出
man 2等待

如果我没记错的话,8位是th
int child_exit_code = -1;
int status = -1;
pid_t pid = wait(&status);
if (-1 != pid)
  child_exit_code = WEXITSTATUS(status);