简体   繁体   English

Linux。 C中的管道。将数据发送到另一个进程。 写作和阅读

[英]Linux. Pipes in C. Sending data to another process. Writing and reading

( Warning - not perfect english!) (警告-不完美的英语!)

On collage they gave me a task to do and I struggling with it for couple of hours and can not solve it. 在拼贴上,他们给了我一个任务,而我奋斗了几个小时而无法解决。 I have a problem with sending data from one process to another. 我将数据从一个进程发送到另一个进程时遇到问题。 In the code below I'm sending input data to child process but I'm not receiving it from child process. 在下面的代码中,我将输入数据发送到子进程,但未从子进程接收它。 Can you guys help with this? 你们可以帮忙吗?

Program description: My job is to take an input from user, sent it to child process using pipe, make some calculations then sent this calculations further to the next process. 程序说明:我的工作是从用户那里获取输入,使用管道将其发送到子流程,进行一些计算,然后将此计算进一步发送到下一个流程。 Last process sums incoming data and assign it to final result. 最后一个过程对输入的数据求和,并将其分配给最终结果。 To be more specific, first child process calculates single terms of Maclaurin series and sends it to process that sums it. 更具体地说,第一个子进程计算Maclaurin系列的单个术语,并将其发送给求和的过程。 Here is the code: 这是代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <sys/stat.h>

int mkfifo(const char *s, mode_t m) {
  return 0;
}

 int i = 1;
 double FINAL_RESULT = 0 ;


double factorial(int N){

    if(N==1)return 1.0;

    return N*factorial(N - 1);

}
double Maclaurine(int i , double x , double eps){

    double result;

     result = (pow(x,(double)i) / (double)factorial(i));

    if( result < eps) return 0;

    return result;

}

void print(char * tab, int size){

    printf("\n");   

    for( int i = 0; i < size ; i++){

        printf("%c" , tab[i]);  

    }   
    printf("\n");   
}



int main(){

    int pd;

    if(mkfifo("tmp/myfifo1", 0666) == -1){

        printf("Failed to create myfifo2\n");
    }

    if(mkfifo("tmp/myfifo2", 0666) == -1){

        printf("Failed to create myfifo2\n");

    }

    pd = open("tmp/myfifo1", O_WRONLY);

    double x1,eps1;

    printf("X Value : \n");
    scanf("%lf", &x1);
    printf("EPS Value : \n");
    scanf("%lf", &eps1);

    char tab1[128], tab2[128];

    //converting to char*
    sprintf(tab1,"%lf",x1);
    sprintf(tab2,"%lf",eps1);

    //printing to standard output
    print(tab1, strlen(tab1));
    print(tab2, strlen(tab2));

    //creating new process
    if(fork() == 0){

        //creating another process
        if(fork() == 0){

            int pd3; 
            pd3 = open("tmp/myfifo2", O_RDONLY);

            char tab5[128];

            double x3;

            //reading data from pipe , myfifo2
            read(pd3,tab5,sizeof(tab5));

            //converting char* to float
            x3 = atof(tab5);

            FINAL_RESULT += x3;
            printf("\nCurrent result = %lf" , FINAL_RESULT);

        }
        int pd2;
        //opening myfifo1 for reading 
        pd2 = open("tmp/myfifo1", O_RDONLY);

        if(pd2 == - 1){

            printf("\nFailed to open myfifo1 for reading!\n");

        }
        double x2, eps2;
        char tab3[128], tab4[128];

        //reading inputed parameters        
        read(pd2,tab3, sizeof(tab3) );

        read(pd2,tab4, sizeof(tab4) );
        //converting to floats
        x2 = atof(tab3);

        eps2 = atof(tab4);

        printf("\nReceived initial data x=%f, eps = %f \n" , x2, eps2);

        double singleTerm = 0;

        int pd4;

        char wyraz[128];

        //opening myfifo2 for writing 
        pd4 = open("tmp/myfifo2", O_WRONLY);

        if(pd4 == -1 ){
            printf("\nfailed to open myfifo2\n");
        }

        do{
            //calculate single term of Maclaurin series
            singleTerm = Maclaurine(i,x2,eps2);
            printf("\n%d. Series term = %lf\n", i,singleTerm);

            sprintf(wyraz,"%lf",singleTerm);

            if(write(pd4, wyraz, sizeof(wyraz)) == -1 ){
                printf("\nfailed to send singleTerm to myfifo2\n");
            }

            i++;
            //if its less than eps, loop ends
        }while(singleTerm);

        printf("\nFinal Result :  %lf", FINAL_RESULT);
        close(pd4);
        close(pd2);

        unlink("tmp/myfifo2");

    }

    //write data to myfifo1
    write(pd, tab1, sizeof(tab1));

    write(pd, tab2, sizeof(tab2));

    close(pd);

    unlink("tmp/myfifo1");

    return 0;

}

And here the result of the code: 这是代码的结果:

pawel@IMPERIUMVB:~$ gcc pipes.c -lm -o x
pawel@IMPERIUMVB:~$ ./x
X Value : 
10
EPS Value : 
0.001

10.000000
0.001000

pawel@IMPERIUMVB:~$ 
Failed to open myfifo1 for reading!
Received initial data x=0.000000, eps = 0.000000 
failed to open myfifo2
1. Series term = 0.000000
failed to send singleTerm to myfifo2
Final Result :  0.000000
Current result = 0.000000
Failed to open myfifo1 for reading!
Received initial data x=0.000000, eps = 0.000000 
failed to open myfifo2
1. Series term = 0.000000
failed to send singleTerm to myfifo2
Final Result :  0.000000

Ok I solved that problem and program gives me expected results. 好的,我解决了这个问题,程序给了我预期的结果。 First key element was to erase 第一个关键要素是擦除

int mkfifo(const char *s, mode_t m) { return 0; }

Just like Jonathan Leffler said *"Including int mkfifo(const char s, mode_t m) { return 0; } in your program means you won't create FIFOs so you can't use them. You need to remove that to use the system call." 就像乔纳森·莱夫勒(Jonathan Leffler)所说的*“在程序中包含int mkfifo(const char s,mode_t m){return 0;}意味着您将不会创建FIFO,因此无法使用它们。您需要将其删除才能使用系统呼叫。”

Second thing was to backing my fifo to beginning over and over after single usage by lseek() function. 第二件事是通过lseek()函数一次又一次地支持我的fifo。 Also I had to clear all my buffers after usage using memset(). 另外,使用memset()后,我还必须清除所有缓冲区。

Here is my code now: 现在是我的代码:

#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <string.h>
#include <math.h>
#include <sys/stat.h>



 int i = 0;
 double FINAL_RESULT = 1.0 ;


double factorial(int N){

    if(N==1 || N == 0)return 1.0;

    return N*factorial(N - 1);

}
double Maclaurine(int i , double x , double eps){

    double result;

     result = (pow(x,(double)i) / (double)factorial(i));

    if( result < eps) return -1.0;

    return result;

}

void print(char * tab, int size){

    printf("\n");   

    for( int i = 0; i < size ; i++){

        printf("%c" , tab[i]);  

    }   
    printf("\n");   
}



int main(){

    umask(0);

    if(mkfifo("myfifo1", 0666) == -1){

        printf("Failed to create myfifo2\n");
    }

    if(mkfifo("myfifo2", 0666) == -1){

        printf("Failed to create myfifo2\n");

    }


    if(fork() == 0){

        int pd = open("myfifo1", O_WRONLY);

        double x1,eps1;
        char tab1[256];
        //assigning tab1 data to 0's

        lseek(pd,0,0);
        memset(tab1, 0, 256);

        printf("X Value : \n");
        scanf("%lf", &x1);


        sprintf(tab1,"%lf",x1);
        //write data to myfifo1
        write(pd, tab1, strlen(tab1));

        printf("EPS Value : \n");
        scanf("%lf", &eps1);

        lseek(pd,0,0);
        memset(tab1, 0, 256);

        //converting to char*
        sprintf(tab1,"%lf",eps1);


        write(pd, tab1, strlen(tab1));

        lseek(pd,0,0);
        memset(tab1, 0, 256);

        close(pd);

        unlink("myfifo1");


        //printing to standard output
        //print(tab1, strlen(tab1));
        //print(tab2, strlen(tab2));

        //creating new process
    }
    else if(fork() == 0){


        int pd2, pd3;
        //opening myfifo1 for reading 
        pd2 = open("myfifo1", O_RDONLY);
        //opening myfifo2 for writing 
        pd3 = open("myfifo2", O_WRONLY);



        if(pd2 == - 1){
            printf("\nFailed to open myfifo1 for reading!\n");
        }


        if(pd3 == -1 ){
            printf("\nfailed to open myfifo2\n");
        }

        double x2, eps2;
        char tab2[256];

        lseek(pd2,0,0);
        memset(tab2, 0, 256);

        //reading inputed parameters        
        read(pd2,tab2, sizeof(tab2) );

        //converting to floats
        x2 = atof(tab2);

        lseek(pd2,0,0);
        memset(tab2, 0, 256);

        read(pd2,tab2, sizeof(tab2) );
        //converting to floats

        eps2 = atof(tab2);

        lseek(pd2,0,0);
        memset(tab2, 0, 256);

        //printf("\nReceived initial data x=%f, eps = %f \n" , x2, eps2);

        double singleTerm = 0.0;


        char wyraz[256];



        while(1){

            //calculate single term of Maclaurin series

            singleTerm = Maclaurine(i,x2,eps2);

            if(singleTerm > 0.0)printf("\n%d. Term of Mac Series = %lf", i+ 1,singleTerm);

            sprintf(wyraz,"%lf",singleTerm);


            lseek(pd3,0,0);

            if(write(pd3, wyraz, sizeof(wyraz)) == -1 ){
                printf("\nfailed to send singleTerm to myfifo2\n");
            }
            if(singleTerm < 0.0){

            //printf("\nI just broke the 1 loop\n");
            memset(wyraz, 0, 256);
            break;
            }


            i=i+1;
        }
        sleep(1);


        close(pd3);
        close(pd2);

        unlink("myfifo2");
        unlink("myfifo1");

    }//creating another process
    else if(fork() == 0){

            int pd4; 
            pd4 = open("myfifo2", O_RDONLY);

            char tab3[256];

            double x3 = 0.0;

            while(1){

            x3=0.0;
            lseek(pd4,0,0);
            memset(tab3, 0, 256);
            //reading data from pipe , myfifo2
            read(pd4,tab3,sizeof(tab3));

            //converting char* to float
            x3 = atof(tab3);

            FINAL_RESULT += x3;


            if(x3<=0.0){

            printf("\nFinal Result :  %lf", FINAL_RESULT ); 
            break;}
            //else
            //printf("\n x = %lf, Current result = %lf" ,x3, FINAL_RESULT);
            }

            sleep(1);

            printf("\nFinal Result :  %lf", FINAL_RESULT);

            close(pd4);
            unlink("myfifo2");

        }

    sleep(7);
    unlink("myfifo1");
    unlink("myfifo2");

    while(1)pause();

    return 0;

}

And now I can see the beauty of mathematical estimations of e^x function by using Maclaurin Series. 现在,我可以使用Maclaurin系列看到e ^ x函数的数学估计的美妙之处。 Here are results: 结果如下:

pawel@IMPERIUMVB:~$ gcc rury.c -lm -o zad1
pawel@IMPERIUMVB:~$ ./zad1
X Value : 
8
EPS Value : 
0.0001

1. Term of Mac Series = 1.000000
2. Term of Mac Series = 8.000000
3. Term of Mac Series = 32.000000
4. Term of Mac Series = 85.333333
5. Term of Mac Series = 170.666667
6. Term of Mac Series = 273.066667
7. Term of Mac Series = 364.088889
8. Term of Mac Series = 416.101587
9. Term of Mac Series = 416.101587
10. Term of Mac Series = 369.868078
11. Term of Mac Series = 295.894462
12. Term of Mac Series = 215.195972
13. Term of Mac Series = 143.463982
14. Term of Mac Series = 88.285527
15. Term of Mac Series = 50.448873
16. Term of Mac Series = 26.906065
17. Term of Mac Series = 13.453033
18. Term of Mac Series = 6.330839
19. Term of Mac Series = 2.813706
20. Term of Mac Series = 1.184718
21. Term of Mac Series = 0.473887
22. Term of Mac Series = 0.180529
23. Term of Mac Series = 0.065647
24. Term of Mac Series = 0.022834
25. Term of Mac Series = 0.007611
26. Term of Mac Series = 0.002436
27. Term of Mac Series = 0.000749

Final Result :  2980.957900 // after adding all of above

e^8 ~ 2980.9579870417 e ^ 8〜2980.9579870417

Estimation is satisfactory :) 估计令人满意:)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM