2013-05-06 1 views
0

숙제가 있으며 SIGCHLD 처리기를 작성하는 동안 문제가 있음을 알리는 것으로 시작합니다. 자식 프로세스 내에서 변수에 액세스해야합니다. 여기 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); 
} 

는 양산 프로세스를 끝나게거야 무슨. 나는 아직 그 일을하지 않았지만.

/* 
* 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); 
} 

나는이 문제를 어떻게 처리 할 것인지 잘 모르겠습니다. 나는 다른 문제의 대부분을 다룰 수 있다고 확신합니다.

+0

OT : 신호 처리기에서'printf()'를 사용하지 마십시오. 반드시 거기에서 호출하기 위해 저장하지 않아도됩니다. 동일한 기능이 다른 많은 기능에도 적용됩니다. 사실 onls에서는 함수의 작은 하위 집합이 비동기 신호 저장 방식으로 구현되도록 정의됩니다. 후자의 목록을 보려면'남자 7 신호'를보십시오. – alk

답변

1

일부 IPC 메커니즘을 사용하지 않고 하위 프로세스는 상위 프로세스에 8 비트의 값만 전달할 수 있습니다.

그 8 비트 exit()에 호출에 매개 변수로 어린이가 보내 wait() 또는 waitpid()에 성공적으로 호출에 의해 반환 status의 값으로 매크로 WEXITSTATUS()을 적용하여 부모 받게된다. 자세한 내용은 man 2 exitman 2 wait을 참조하십시오.

올바르게 기억한다면 표준에 정의 된대로 8 비트가 최소값입니다. 일부 구현은 더 많은 비트를 허용 할 수 있습니다.

업데이트 : wait()을 사용하는 방법에 대한

예 :

int child_exit_code = -1; 
int status = -1; 
pid_t pid = wait(&status); 
if (-1 != pid) 
    child_exit_code = WEXITSTATUS(status); 
+0

그래서 기본적으로 자식 프로세스가 끝날 때 보낼 필요가있는 것과 동일한 상태로 설정되어 있습니까? 그리고 'WEXITSTATUS()'를 사용하여 필요한 것을 얻으십시오. –

+0

@nateperrone : "필요한 것"이 8 비트 너비보다 크지 않으면 2^8 = 256 개의 다른 값이 필요하지 않습니다. 그렇습니다. 그렇습니다. – alk

0

당신은 공유 메모리를 할당 할 수 shmget를 사용할 수 있습니다.

포크 전에 사용하면 할당 된 메모리에 자식과 부모가 모두 액세스 할 수 있습니다.
아이는 그곳에 원하는 것을 저장할 수 있으며, 부모는 그것을 읽을 것입니다.

관련 문제