如何在fork之后正确使用exec()系统调用?

时间:2014-06-26 06:20:16

标签: c exec fork

我的程序出现问题我想让run_uptime函数每隔5秒向stdout显示正常运行时间函数的输出。但是,我不知道我在代码中做错了什么,我查看了与exec()和fork()相关的各种其他问题,但我似乎仍无法找到解决方案。另一件事是如何在没有switch语句的情况下重写fork调用,但这更多是一个美学原因,但我仍然想知道如何去做。我很感激任何帮助。请解释原因,因为我是新手。

问题陈述,程序应该做什么:

您应创建一个执行以下操作的程序:

o启动时,读取用户希望程序运行的总运行时间(以秒为单位)。如果用户不包括启动程序的时间,则将使用默认值10秒(即,rohan> a3 30导致程序运行30秒,rohan> a3将运行程序10秒)。

o程序应创建三个子进程,然后忙等待直到所有子进程完成然后退出。

o第一个子进程应实现一个时钟,每秒打印一小时,分钟和秒(在人类可读的本地时间)

o第二个子进程应每5秒运行一次正常运行时间(/ usr / bin / uptime)

o第三个子进程应实现倒数计时器,打印剩余的分钟和秒数,每秒一次,直到达到00:00。

o第三个子进程在到达00:00时,应通知(信号,管道或......等,您选择的IPC机制)第一个和第二个子进程'(即它的兄弟进程)他们终止然后终止自己。

o所有子进程终止后,父进程应打印一条友好消息,然后退出。

这是我的代码,它编译但我需要一个不同的输出。

/* Include Files */
#include <stdio.h>
#include <time.h> /* for local time functions */
#include <unistd.h> /* for fork */
#include <string.h>
#include <stdlib.h>
#include <sys/wait.h> /* for wait function */
#include <sys/types.h> /* for pid_t */

/* remember 0 means program finished correctly, by unix convention */

/* Definitions */
#define TIME_QUANTUM 5 //Default time for program to run!

/* Functions */
void system_clock(void); //function to display human readable time.
void time_to_kill(int timequota); //prints out the time in a countdown fashion, till program ends.
void run_uptime(void);

/* Variables */
int procpipe1[2]; //Allocate Pipe Set 1
int procpipe2[2]; //Allocate Pipe Set 2
char bufkill[12]; //Buffer to hold kill signal, to tell other processes to end.


    int main(int argc, const char * argv[])
{
    int time=TIME_QUANTUM;
    if(argc==2)
    {
        time=atoi(argv[1]); //looking to see if user wants a custom running time.
    }

   //Creating pipes before creating child processes, so they could communicate.
   pipe(procpipe1);
   pipe(procpipe2);

   printf("Pipes opened, now creating child process!\n");

    //Create Child Processes and run associated functions in them.
    //Creating the the 1st child process!

    switch (fork())
    {
        case -1:
            printf("Error: couldn't create 1st Child!\n");
            exit(1);

        case 0: //If no error in creating child process then create process!
            printf("\nChild 1 process: time_to_kill executing...\n");
            system_clock();
            exit(1);

        default:
            break;
    }

    //Creating the 2nd child process!
    switch (fork())
    {
        case -1:
            printf("Error: couldn't create 3rd Child!\n");
        case 0: //If no error in creating child process then create process!
            printf("\nChild 2 process: time_to_kill executing...\n");
            run_uptime();
            exit(1);

        default:
            break;
    }

    //Creating the 3rd child process!
    switch (fork())
    {
        case -1:
            printf("Error: couldn't create 2nd Child!\n");
            exit(1);
        case 0: //If no error in creating child process then create process!
            printf("\nChild 3 process: time_to_kill executing...\n");
            time_to_kill(time); 
            exit(1);

        default:
            break;
    }

    printf("Parent closing pipes\n");

    //Need to close the pipes after using them, close communications between processes.
    //pipe close error checking

    close(procpipe1[0]);
    close(procpipe1[1]);
    close(procpipe2[0]);
    close(procpipe1[1]);

    printf("Parent waiting for children completion...\n");

    //Wait for child processes to end before ending Main, the overall process 
    //that spawned the child processes.

    wait(NULL);
    wait(NULL);
    wait(NULL);

    printf("Time to print out a Friendly Message!\n");
    printf("Parent process finishing, bye!\n");
    exit(EXIT_SUCCESS);   
}//end main

//This is the 1st Child Process
void system_clock(void) 
{
    /* variable of system_clock()*/
    //temp buffer to get termination string
    char str1[12];
    time_t now;
    struct tm *lcltime;

    strcpy(str1, "time to die"); //store this string into str1 local variable

    close(procpipe1[0]);
    close(procpipe1[1]);
    close(procpipe2[1]);

    //show current time
    for(;;)
    {
        now = time ( NULL );
        lcltime = localtime ( &now );

        //read message from child 2 process
        int status = read(procpipe2[0], bufkill, 12);

        if ((strcmp(str1, bufkill)) != 0)
        {
            //printf("Read status: %d, Buffer= %s\n", status, bufkill);
            printf ("The time is %d:%d:%d\n", lcltime->tm_hour, lcltime->tm_min, lcltime->tm_sec );
            //show ever second
            sleep(1);
        }


        //if end signal came in
        //if(ret == 0)
        if ((strcmp(str1, bufkill)) == 0)
        {
            //close reading end
            close(procpipe2[0]);

            //return back to parent
            printf("Child 1 process: system_clock ending...\n");
            exit(1);
        }
    }  
}//end system_clock

//This is the 2nd Child Process
void run_uptime() 
{
    // variable of run_uptime
    //temp buffer to get termination string
    char str1[12];

    strcpy(str1, "time to die"); //store this string into str1 local variable

    close(procpipe1[0]);
    close(procpipe1[1]);
    close(procpipe2[1]);    

    for(;;)
    {
        //read message from child 2 process
        int status = read(procpipe2[0], bufkill, 12);

        if ((strcmp(str1, bufkill)) != 0)
        {
            //printf("Read status: %d, Buffer= %s\n", status, bufkill);
            execl("/usr/bin/uptime","uptime",NULL);
            //show ever 5 seconds
            sleep(1);
        }


        //if end signal came in
        if ((strcmp(str1, bufkill)) == 0)
        {
            //close reading end of pipe.
            close(procpipe2[0]);

            //return back to parent
            printf("Child 2 process: run_uptime ending...\n");
            exit(1);
        }
    }  
}//end run_uptime

//This is the 3rd Child Process
void time_to_kill(int timequota) //This process signals the other processes to stop.
{
    /* Need to change this signal */
    //string signal to end process 
    strcpy(bufkill, "time to die");

    //Pipes that aren't being used close them.
    close(procpipe1[0]);
    close(procpipe1[1]);
    close(procpipe2[0]);

    for( ;timequota>0; timequota--)
    {
        printf("Count Down: 00:0%d\n", timequota);
        //send signal to child 1 process and child 2 process not to end
        write(procpipe2[1], "not die yet",12); //write into pipe2 statement that doesn't signal stopping process.
        //count down every second
        sleep(1);
    }

    //send signal to child 1 process and child 2 process to be terminate itself.
    write(procpipe2[1], bufkill, sizeof(bufkill)); //write into pipe2 the kill statement stored in bufkill

    //close pipe 2 writing end
    close(procpipe2[1]); 

    //back to main
    printf("Count Down: 0\n");
    printf("Child 3 process: time_to_kill ending...\n");
    exit(1);
}//end time_to_kill

0 个答案:

没有答案