I am trying to write a program so that the parent and child process can communicate back and forth between each other. The parent process and the child process ought to print the values from 1-100 where each process prints the value incrementing it by 1 each time. Now the issue I face is that, I know nothing much about pipes. What I gather from reading materials online is that I can use a pipe to read and write values. I have leveraged this to print something in the child process, and send back something to the parent. Now, I am not sure how to get the parent to return to the child after printing for itself? I know my code is probably all wrong, but I am really not sure what I should do.
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, const char * argv[]) {
int fd[2];
if (pipe(fd)== -1){
printf("An error occured while opening the pipe\n");
}
int id = fork();
int i = 0;
if (id == 0){
close(fd[0]);
printf("In child: %d", i);
i ++;
write(fd[1], &i, sizeof(int));
close(fd[1]);
} else {
wait(NULL);
close(fd[1]);
int y;
read(fd[0],&y, sizeof(int));
close(fd[0]);
}
}
To keep it simple, it's up to you to check return values and handle errors. This will only do it between 0 - 9 and you will have to expand the mathematics.
#include <sys/types.h>
#include <sys/wait.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
int main(int argc, char *argv[])
{
int pipefd_1[2];
int pipefd_2[2];
pid_t cpid;
pipe(pipefd_1);
pipe(pipefd_2);
cpid = fork();
if (cpid == 0) { /* Child reads from pipe 1, writes to pipe 2*/
char cval[] = {'0'};
close(pipefd_1[1]); /* Close unused write and read ends */
close(pipefd_2[0]);
while (atoi(cval) != 9) {
read(pipefd_1[0], cval, 1);
printf("Child print %d\n", atoi(cval));
cval[0] += 1;
write(pipefd_2[1], cval, 1);
}
} else {
char cval[] = {'0'}; /* Parent writes buf to pipe 1 */
close(pipefd_1[0]); /* Close unused read end */
close(pipefd_2[1]);
while (atoi(cval) != 9) {
write(pipefd_1[1], cval, 1);
read(pipefd_2[0], cval, 1);
printf("Parent print %d\n", atoi(cval));
cval[0] += 1;
}
}
}
Output
Related
Hello I'm struggling right now with C language and process so basically I've just learnt about pipe and I want to use them just to exercise myself on it, so I want to try a code that basically use two child and 1 father, by one child the user enter some number then this child send those numbers to the other child and then this second child send them to the father who show them.
here my code so far
`
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <limits.h>
#include <string.h>
int main(int argc, char const *argv[])
{
pid_t son1;
pid_t son2;
int Pipe1[2];
int pipe2[2];
int sent=0;
int sent2=0;
int recive=0;
int recive2=0;
int j=0;
int mem[3];
if (pipe(Pipe1)==-1)
{
printf("error pipe1");
exit(0);
}
if (pipe(pipe2)==-1)
{
printf("error pipe2");
exit(0);
}
son1=fork();
if (son1==0)
{
close(Pipe1[0]);
//close(pipe2[0]);
//close(pipe2[1]);
printf("i'am the child 1\n");
for (int i = 0; i < 3; i++)
{
printf("type your number \n");
scanf("%d",&sent);
write(Pipe1[1],&sent,sizeof(int));
}
close(Pipe1[1]);
}
son2=fork();
if (son2==0)
{
close(Pipe1[1]);
close(pipe2[0]);
printf("i'am the son number 2 \n");
recive=read(Pipe1[0],&sent,sizeof(int));
while(recive == sizeof(int))
{
printf("nb reçu %d \n",sent);
mem[j]=sent;
recive= read(Pipe1[0],&sent,sizeof(int));
j++;
}
close(Pipe1[0]);
for (int p = 0; p < 3; p++)
{
sent2=mem[p];
printf("sent2 %d",sent2);
write(pipe2[1],&sent2,sizeof(int));
}
close(pipe2[1]);
when i run this code it does work but not how i expect, the commmunication between children work but not between child 2 and the father actualy if you look at the second part of the code of son2 "mem[]" value is not the same before close(pipe[1]) and after and this is why the comunication is mestup but i realy dont know how the value can change.. if someone can explain me it will be really kind of him
`
You create two pipes in the parent which are shared with the children, and the children do not share a pipe with each other. The easiest thing is probably to move the 2nd pipe to the child and have it fork the 2nd child:
#include <stdio.h>
#include <stdlib.h>
#include <sys/wait.h>
#include <unistd.h>
int main(void) {
int parent_child[2];
if(pipe(parent_child) == -1) {
printf("pipe failed\n");
exit(1);
}
if(!fork()) {
close(parent_child[0]);
int child_grand_child[2];
if(pipe(child_grand_child) == -1) {
printf("pipe failed\n");
exit(1);
}
printf("child write\n");
write(child_grand_child[1], "1", 1);
if(!fork()) {
char buf[1];
ssize_t n = read(child_grand_child[0], buf, sizeof buf);
printf("grand child read\n");
write(parent_child[1], buf, n);
exit(0);
}
close(parent_child[1]);
wait(&(int) {0});
exit(0);
}
close(parent_child[1]);
char buf[1];
ssize_t n = read(parent_child[0], buf, sizeof buf);
printf("parent read %*s\n", n, buf);
wait(&(int) {0});
}
which outputs:
child write
grand child read
parent read 1
I'm new to C and linux system programming.
I have created 2 pipes for bi-directional communication between parent and child processes. I am reading numbers in parent for e.g:
1 2(enter)
(enter) means pressing enter to get to new line.
Using pipes, I'm sending this input to child process, who I want to compute the sum for the numbers. Then using another pipe, I'm sending the sum back to parent for printing.
When I run the code the output doesn't show. It's like this:
./a.out
2 3
hamzasidiki#Hamza-PC:~/Desktop/SPMukhi/New$
As you can see the program is not printing the result and ending before. What's wrong in my code? Any help is appreciated. TIA.
#include <unistd.h>
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <sys/types.h>
#include <sys/wait.h>
int main() {
int fd1[2];
int fd2[2];
pid_t cpid;
int wstatus;
pipe(fd1);
pipe(fd2);
cpid = fork();
if(cpid == -1) {
perror("fork");
exit(0);
}
if(cpid > 0) {
//Parent
int rc;
char pbuff[20];
int rcp1 = read(STDIN_FILENO, pbuff, 20);
close(fd1[0]);
write(fd1[1], pbuff, rcp1);
close(fd1[1]);
waitpid(cpid, wstatus, 0);
close(fd2[1]);
char pbuff1[20];
int rcp2 = read(fd2[0], pbuff1, 20);
pbuff1[rcp2 - 1] = '\0';
close(fd2[0]);
write(STDOUT_FILENO, pbuff1, rcp2);
}
if(cpid == 0) {
//Child
int sum = 0;
char cbuff[20];
close(fd1[1]);
int rcc = read(fd1[0], cbuff, 20);
cbuff[rcc - 1] = '\0';
char *a = strtok(cbuff, " ");
while(a != NULL) {
int a = atoi(a);
sum += a;
a = strtok(NULL, " ");
}
close(fd1[0]);
close(fd2[0]);
char w[20];
int n = sprintf(w, "Result = %d\n", sum);
write(fd2[1], w, n);
close(fd2[1]);
}
}
It worked for me after clearing out the warnings my compiler gave me.
Use a different variable name for the integer a in the while loop of your child code. It's confusing the atoi() function call.
waitpid() expects a pointer in its second argument where you've provided an integer. Pass &wstatus instead or just NULL since you're not using the status anyway.
I'm supposed to return the sum of first 12 terms of Fibonacci series from child process to parent one but instead having 377, parent gets 30976.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t childpid;
int i, fib_sum=0, fib1=1, fib2=1, temp, status;
childpid=fork();
if(childpid!=0)
{
wait(&status);
fprintf(stderr, "%d\n", status);
}
else
{
for(i=1; i<=12; i++)
{
temp=fib1;
fib_sum=fib1+fib2;
fib1=fib_sum;
fib2=temp;
}
fprintf(stderr, "%d\n", fib_sum);
return fib_sum;
}
}
What am I doing wrong?
I'm supposed to return the sum of first 12 terms of Fibonacci series
from child process to parent one but instead having 377, parent gets
30976.
Process exit status is limited in value, therefore it is not the best way to communicate a value between child and parent.
One of the solution is to pass the calculated value using pipes.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
int main(int argc, char *argv[])
{
pid_t childpid;
int i, fib_sum=0, fib1=1, fib2=1, temp, status;
int fd[2];
int val = 0;
// create pipe descriptors
pipe(fd);
childpid = fork();
if(childpid != 0) // parent
{
close(fd[1]);
// read the data (blocking operation)
read(fd[0], &val, sizeof(val));
printf("Parent received value: %d\n", val);
// close the read-descriptor
close(fd[0]);
}
else // child
{
// writing only, no need for read-descriptor:
close(fd[0]);
for(i=1; i<=12; i++)
{
temp = fib1;
fib_sum = fib1+fib2;
fib1 = fib_sum;
fib2 = temp;
}
// send the value on the write-descriptor:
write(fd[1], &fib_sum, sizeof(fib_sum));
printf("Child send value: %d\n", fib_sum);
// close the write descriptor:
close(fd[1]);
return fib_sum;
}
}
Test:
Child send value: 377
Parent received value: 377
If you can't use pipes, which would be the optimal solution here, you could save the result to a file that the parent would read from. Pass the name of the file to save the result to from parent to child. In your child process, you would do:
int main(int argc, char *argv[])
{
int fib_sum=0;
if (argc <= 1)
{
print_usage();
return 1;
}
//... calculate fib_sum
FILE *f = fopen(argv[1], "w");
if (f == NULL)
{
printf("Error opening file!\n");
return 1;
}
fprintf(f, "%d", fib_sum);
return 0;
}
Then in your parent process:
int n = 0;
FILE* f;
//... spawn child and wait
FILE *f = fopen(file_name, "r");
fscanf(f, "%d", &n);
I am doing this homework for some time and it's giving me a headache.
Write a program that writes the integer “i+1” into element “i” of a table of MAXBUF
integers (for every element of the table). MAXBUF should be initially “#define”d as 10 in the source
code of the program. Then, using only one write() operation, the program should write the entire
table of integers in binary format into an initially truncated file, named “filetable.bin”. In the next
step the program should create a child process, and then print the message “The parent process
is terminating.”, and then exit. The child process should separately read, in binary format, from
the file each integer in the same order as the integers are stored in the file, and print each such
integer to the standard output. In the final step of the program, the child process should wait for its
parent process to terminate, and then print to the standard output the message “The child process
is terminating.”, and then terminate. All the operations on the “filetable.bin” file should be
performed using system calls.
#include <fcntl.h>
#include <sys/stat.h>
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <signal.h>
#define MAXBUF 10
int decimalToBinary(int n);
int main(int argc, char *argv []) {
int i, fd, n, status, childpid;
char buffer[MAXBUF];
pid_t pid = (long)getpid();
fd = open("filetable.bin", O_CREAT | O_RDWR);
for(i=0; i<MAXBUF; i++) {
n=i+1;
buffer[i] = decimalToBinary(n);
}
write(fd,buffer,sizeof(buffer));
childpid = fork();
if(childpid >0) {
printf("The parent process terminating.\n");
exit(0); // or kill(pid, SIGKILL)
}
if(childpid < 0) {
perror("Failed to fork\n");
}
else {
read(fd,&childpid,sizeof(childpid));
write(STDOUT_FILENO,&childpid,sizeof(childpid));
wait(&status);
printf("The child process is terminating\n");
exit(1);
}
return(0);
}
int decimalToBinary(int n) {
int remainder, binary=0, i=1;
while(n!=0) {
remainder = n%2;
n = n/2;
binary = binary + (remainder*i);
i = i*10;
}
return binary;
}
My problem is how do I read from the childpid and write with it in STDOUT?
EDIT: It appears in the output: "The parent process is terminating\n" "The child process is terminating\n". It's missing the STDOUT
I can't get this basic communication to work.
All I want to do, is send information via the child's stdout to the parents file descriptor.
I am getting a seg fault.
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#define READ 0
#define WRITE 1
int main(void){
int fdRead[2];
int pid, i, num;
FILE* output;
char mystring [100];
char c;
pid = fork();
if(pid){
FILE * read;
close(fdRead[WRITE]);
read = fdopen(fdRead[READ], "r");
fgets(mystring,100, read);
printf("parent %d",mystring );
} else {
/* child */
dup2(fdRead[WRITE], STDOUT_FILENO);
close(fdRead[READ]);
close(fdRead[WRITE]);
printf("child" );
}
exit(0);
}
Your code does nothing about pipe.
Code for communicating between parent and child processes using pipe looks as follows
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#define READ 0
#define WRITE 1
int main(void){
int pipefd[2];
pid_t pid;
int i, num;
if (pipe(pipefd)<0) { /* create pipe */
perror("pipe");
exit(-1);
}
char mystring [100];
char c;
pid = fork();
if(pid<0){
perror("fork");
exit(-1);
} else if (pid=1) { /* parent */
char *mystring = "message to child";
write(pipefd[WRITE],mystring,strlen(mystring);
sleep(1); /* wait for child read message */
char buf[128]; /* buffer to receive data from child */
read(pipefd[READ],buf, sizeof buf);
close(pipefd[READ]);
close(pipefd[WRITE]);
printf("Returned from child %s",buf );
return 0;
} else { /* child */
char *s="send from child: ";
char buf[128];
read(pipefd[READ],buf, sizeof buf);
write(pipefd[WRITE],s,strlen(s));
close(pipefd[READ]);
close(pipefd[WRITE]);
return 0;
}
}