【问题标题】:Program in C language using pipe and fork?使用管道和叉子用 C 语言编写程序?
【发布时间】:2013-11-15 23:14:28
【问题描述】:

我有一个任务,我必须解决这个问题...我是 C 的完全新手,我仍在努力学习 C。

问题来了

编写一个创建管道和子进程的程序。父母反复设置警报 15 秒。触发警报时,父级计算自启动以来经过的秒数和微秒数,并通过管道将这些发送给子级。在获得信息时,孩子将它们显示在屏幕上。整个持续2分钟。

我已经尝试过这个问题,但我有很多错误..

这是我的解决方案..

#include <string.h>
#include <stdio.h>
#include <unistd.h>
#include <sys/types.h>
#include <stdlib.h>
#include <time.h>


int main(void)
{
        int     fd[2], nbytes;
    int fd2[2];
        pid_t   childpid;
        char    readbuffer1[80];
    char    readbuffer2[80];

         clock_t start, stop;
         long count;
         double time_sec, time_milli;
    const char* time1, time2;

        pipe(fd);
    pipe(fd2);
        childpid = fork();



        if(childpid == -1)
        {
                perror("fork");
                exit(1);
        }

        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[1]);


        /* Read in a string from the pipe */
        read(fd[0], readbuffer1, sizeof(readbuffer1));
        read(fd2[0], readbuffer2, sizeof(readbuffer2));
                printf("Received string 1: %s", readbuffer1);
        printf("Received string 2: %s", readbuffer2);

        }
        else
        {
                start = clock();
                /* Parent process closes up output side of pipe */

                alarm(15);
                /* Send "string" through the output side of pipe */


                stop = clock();



                time_sec = (double)(stop-start)/CLOCKS_PER_SEC;
        time_milli = time_sec*1000;
        sprintf(&time1,"%f",time_sec);
        sprintf(&time2,"%f",time_milli);
        close(fd[0]);
        write(fd[1], time1, (strlen(time1)+1));
        write(fd2[1], time2, (strlen(time2)+1));

        }

        return(0);
}

如何让这个运行 2 分钟?我怎样才能重复运行警报 15 秒?请帮忙....

【问题讨论】:

    标签: c linux fork pipe


    【解决方案1】:

    好的。我已将您的代码更正如下。您可以直接编译并运行它。它应该可以工作。

    您的代码有几个问题:

    1. 您应该在 sprintf 之前为 time1 和 time2 分配内存空间。

    2. 您应该使用 time() 而不是 clock()。看: clock() function always returning 0

    3. 使用 sleep() 代替 alarm()

    希望对您有所帮助!

    #include <string.h>
    #include <stdio.h>
    #include <unistd.h>
    #include <sys/types.h>
    #include <stdlib.h>
    #include <time.h>
    
    
    int main(void){
    
    
    int     fd[2];
    int     nbytes;
    int     fd2[2];
    pid_t   childpid;
    char    readbuffer1[80];
    char    readbuffer2[80];
    
    time_t start, stop;
    long count;
    double time_sec, time_milli;
    char* time1;
    char* time2;
    
    pipe(fd);
    pipe(fd2);
    childpid = fork();
    
        if(childpid == -1)
        {
                perror("fork");
                exit(1);
        }
    
        if(childpid == 0)
        {
                /* Child process closes up input side of pipe */
                close(fd[1]);
    
          /* Read in a string from the pipe */
          read(fd[0], readbuffer1, sizeof(readbuffer1));
          read(fd2[0], readbuffer2, sizeof(readbuffer2));
    
              printf("Received string 1: %s", readbuffer1);
          printf("Received string 2: %s", readbuffer2);
        }
        else
        {
    
            close(fd[0]);
    
            time(&start);
    
              sleep(15);
    
              time(&stop);
    
          time_sec = stop-start;
          time_milli = time_sec*1000;
    
          time1 = malloc(80);
          time2 = malloc(80);
    
          sprintf(time1,"%f",time_sec);
          sprintf(time2,"%f",time_milli);
    
    
          write(fd[1], time1, (strlen(time1)+1));
    
          write(fd2[1], time2, (strlen(time2)+1));
    
        }
    }
    

    【讨论】:

    • 足够接近了。 OP 仍然需要修复循环、总运行限制和不必要的管道。另外,学会循环使用readwrite
    • 你的答案很好,刚刚测试过.. 谢谢.. 但正如 SpecialTrooper 指出的那样,我认为我犯了一个错误,我应该只使用 1 个管道将这 2 个值传递给孩子。 ..问题说当警报被触发时,我想我应该使用 alarm() 而不是 sleep() ...
    • @user2228135 - alarm 可能更合适,但请注意,您必须为 SIGALRM 设置信号处理程序,因为默认处置是终止进程。
    【解决方案2】:

    首先,如果你运行你的代码,你会得到什么错误?

    我在您的代码中看到的第一个问题是您正在创建两个管道,而不是问题中提到的一个!!!

    这应该创建一个合适的管道,你可以在其中做你的事情

    编辑:我刚刚在我的代码中添加了一个简单的一次性通信。您所要做的就是将所有内容包装在一个循环中,该循环运行 2 分钟并在正确的时间发送警报。

    #include <stdio.h>
    #include <stdlib.h>
    #include <unistd.h>
    
    int main()
    {
            int pipefd[2];
            int rt;
            pid_t child = 0;
    
            // An array with some values
            char charBuffer[10] = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9' };
            // A buffer we use to communicate over the pipe
            char outputBuffer[10];
    
            if( pipe(pipefd) == -1 ) // Create new pipe
            {
                    fprintf(stderr, "Failed to create pipe\n");
                    exit(1);
            }
    
            child = fork();        // Create new Child
    
            if( !child )
            {
                    printf("child created\n");
                    close(pipefd[1]); // Child is read only
    
                    // Wait for your alarm here
                    while( read(pipefd[0], (void*)&outputBuffer, 10) > 0 )
                    {
                        printf("Child received something over the pipe\n");
                        // Write output direct to stdout
                        rt = write(STDOUT_FILENO, &outputBuffer, 10);
                        rt = write(STDOUT_FILENO, "\n", 1);
                    }
            }
            else if( child == -1 )
            {
                    fprintf(stderr, "Error on fork - no child\n");
                    exit(2);
            }
            else if( child > 0 )
            {
                    close(pipefd[0]); // Parent is write only
    
                    // Write our values to the pipe
                    rt = write(pipefd[1], &charBuffer, 10);
    
                    printf("Parent finished writing\n");
                    close(pipefd[1]); // Signal writing is finished
            }
    
            return 0;
    }
    

    【讨论】:

    • 嘿,你的代码很好,你能给我解释一下,如何等待和发送警报...我还在努力学习 C...任何帮助将不胜感激.. .
    • 我在上面的代码中添加了一个简单的通信。它只是将一些字符从父母发送给等待的孩子:-)。
    【解决方案3】:

    您只需 sleep 15 秒,然后将其包装成一个循环

    for (int i = 0; i < 8; ++i) {
        sleep(15);
        /* do something, talk to your child, ... */
    }
    

    【讨论】:

    猜你喜欢
    • 2015-08-24
    • 2015-08-19
    • 1970-01-01
    • 2016-07-05
    • 2011-07-16
    • 2017-07-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多