( 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. 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."
Second thing was to backing my fifo to beginning over and over after single usage by lseek() function. Also I had to clear all my buffers after usage using 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. 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
Estimation is satisfactory :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.