I'm trying to figure out how the following program i wrote for a raspberry pi with led matrix works.
The program is supposed to have a child process forked by the main process light up the LED from 0,0 -0,8 in first iteration for num=0. But instead, the LEDs light up randomly in the 0th column.
Example : in 0th column 0,6,4,5,2,3,1
in 1st column 0,6,5,4,2,3,1
and so on till 8th column.
I'm confused as to why the "main" for loop controlling the rows runs randomly ,but the second loop controlling the columns works in an orderly increasing fashion.
What am I missing in the working of fork together with a for loop?
From the output I can only guess that the parent is somehow creating random child processes all at once that are calling function2 with their randomized num argument.
<header files>
function1
{ creates a delay of a second through calculations }
function2(n)
{ for(int i = 0; i<=8 ;i++)
function1;
printf("LED(%d,%d)\n",n,i);
}
main()
{
for(int num = 0; num <=7; num++)
{
pid_t pid = fork();
if (pid ==0)
{ function2(num); }
}
for (int num =0; num <= 7; num++)
{ wait(NULL);}
}
Father and child processes do run concurrently, and it is not predictable which process is running at what time.
From a first inspection you have a loop that starts from the father process and creates 8 child processes, that on their hand each creates other child processes! You should terminate the child process after calling the function2, otherwise the child processes will create other processes.
I think the solution to your problem is something like this:
#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
void function1() {
//0.5 seconds sleep
usleep(500000);
}
void function2(int n) {
for(int i = 0; i <= 8; i++) {
function1();
printf("LED(%d,%d)\n", n, i);
}
}
int main()
{
pid_t pid;
for(int num = 0; num <= 7; num++) {
pid = fork();
if (pid == 0) {
function2(num);
exit(0);
}
}
for (int num = 0; num <= 7; num++){
wait(NULL);
}
return 0;
}
Please for future questions please post a Minimal, Complete, and Verifiable example.
The code could also have a concurrency problem, I don't think the printf is an atomic function, so a semaphore may be necessary to avoid having multiple processes calling the printf.
Another note is that a check should be fork() to check if the child process was successfully generated.
Related
I'm a bit confused with the creation of processes with fork(), sleep() and wait() in c. Take the following piece of code:
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
void childProcess(void);
void childProcess(void)
{
for(int i = 0; i < 5; i++)
{
printf("pid: %d email: myemail\n", getpid());
sleep(1);
}
}
int main(int argc, char *argv[])
{
for (int i = 0; i < 5; i++)
{
pid_t childpid;
if ((childpid = fork()) == 0)
{
childProcess();
exit(0);
}
}
int status;
while (wait(&status) > 0)
{
}
return 0;
}
After this piece of code has been executed,executes processes but does not remove repetitions from 5 processes. I'm a little confused with the process.
The initial process creates 5 child processes, and waits for them to finish.
Each child process performs 5 repetitions, where in each repetition:
Prints the message
pid: PID email: USER_EMAIL
where PID is the child PID of the process, while USER_EMAIL is the email
Suspends its operation for 1 second (at a time) with the sleep call
The parent process prints the children's PIDs when they are finished
P.S I EDIT THE CODE
#mixalispetros, you have multiple things to fix, and they all have to be fixed together for your code to work as intended.
exit(0);
for (int i = 0; i < 5; i++) {
wait(NULL);
}
The process ends on exit(0). wait is never called.
if (fork() == 0) {
// what code runs here? The code in the new process
}
What code runs within the fork() conditional? The new process's code. Which process should run wait()? The original process. So in addition to being after an exit, the wait() is also in the wrong process.
Where to move it? The for loop wait()s for 5 child processes. Why would there be 5 child processes for which to to wait()? Because we had already started all 5 child processes before we went into our loop of 5 wait()s.
The wait()s must happen not just outside the child process conditional block, but also outside the loop around the call to fork().
I'm a bit confused with the creation of processes with fork(), sleep() and wait() in c
It is confusing. Refer to the documentation often to keep it straight.
Remember, fork() returns twice - in the original process (returning the process ID of the new process), and in the new process (returning 0). wait(), will wait for the next child process to exit.
In summary, put the wait loop outside the loop that fork()s child processes. This will also move it ouside the block of code that executes in the child process.
#include <stdio.h>
#include <unistd.h>
#include <stdlib.h>
#include <sys/wait.h>
int main() {
// this loop creates 5 processes
for (int i = 0; i < 5; i++) {
if (fork() == 0) {
printf("Child %d, PID %d\n", i, getpid());
sleep(i);
exit(0);
}
}
// now, all subprocesses were started
// wait for the same number of child processes to end
for (int i = 0; i < 5; i++) {
wait(NULL);
}
}
Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 4 years ago.
Improve this question
I am new to C , So i only know simple functions.(ex: wait(NULL) ).
Here is my main question :
Modify the program so that only the parent process creates 3 child processes, and each
new created process calls a function CPU(). In addition, make the parent process wait for
each child’s termination.
I know this one is the correct answer
#include<stdio.h>
int main(void)
{
int i ;
for( i = 0; i < 3; i++)
{
int ret = fork();
if(ret == 0){
printf("My process ID is %d\n", getpid());
return 0;
}
}
for (i = 0; i < 3; i++) //Line B
wait(NULL);
}
but my problems are
why below code is wrong when wait is executed by the parent in the loop
#include <stdio.h>
int main(void)
{
int i ;
for( i = 0; i < 3; i++)
{
int ret = fork();
if(ret == 0) {
printf("My process ID is %d\n", getpid());
return 0;
}
else
wait(NULL);
}
}
in very first code why do we write wait(NULL) inside a for loop?
can't we write it without a for loop
if there is no "return 0" in child process, should the for loop be changed to
for (i = 0; i <7; i++)
wait(NULL);
I don't know how to write the CPU function
This code would not execute the child processes in parallel but execute each one sequentially. The difference does not show until the child processes do something beyond printing one message and exiting (you could add sleep(1)).
wait function will wait for the termination of one child process (whichever finishes first). If you've got 3 child processes, you must call wait successfully at least that 3 times to ensure that each one of them has terminated. Perhaps easier would be to call wait until it sets errno to ECHILD, meaning that there are no children left:
while (1) {
errno = 0;
if (wait(NULL) == -1) {
if (errno != ECHILD) {
perror("Unexpected error from wait");
}
break;
}
}
Each parent process should wait for its own children (or set the SIGCHLD disposition to SIG_IGN). Instead of counting the number of waits, use the code above
This means just: "call a function by the name CPU", i.e.
void CPU(void) {
}
in the child process.
BTW, your code is missing the necessary headers for a couple functions -
#include <sys/types.h>
#include <sys/wait.h>
for wait,
#include <unistd.h>
for fork and additionally #include <errno.h> for my errno addition.
I've read a few threads on here for information on this. I understand some but most of them are written in different methods. I just cant find sufficient information on how to return a value from a child process through a return statement. I blame myself for not looking hard enough, but i'm at a muddy puddle stuck. Any information is appreciated thanks.
My goal for this (school assignment) is to have a child process read information from the parent. The child will ten compute mathematically (addition) each value received from the parent, then send the final value back to the parent to print onto the screen.
RULES:
1. Can't use command line args inside of a child process only parent
2. All mathematical computation must be inside of child process.
3. No error checking is needed.
Here is some code of what i have:
int main(int argc, char **argv){
char buf[256];
int pipeCommunication[2];
pipe(pipeCommunication);
pid_t pid = fork();
if(pid == 0){
//inside child process
int sum = 0;
read(pipeCommunication[0], buf, sizeof(buf));
sum += atoi(buf);
return sum; //WHY DOES IT NOT RETURN THE VALUE OF SUM?
}else{
int sum = 0;
for(int i = 1; i<argc;i++){
write(pipeCommunication[0], argv[i], sizeof(argv);
wait(NULL);
}
printf("sum = %d\n", sum); //WHY CANT I SEE THE VALUE OF SUM FROM CHILD?
return 0;
}
}
Command line input would be: ./apprun 1 2 3
OUTPUT: 6
(added 1 + 2 + 3 = 6)
EDIT: I've realize that perhaps my write or read func need to cleared to allow another value to be read into the child process. Still trying to figure that out.
EDIT: I've completed the assignment and will post the result here if anyone wants to view the final code. Afterwards, this thread is completed.
#include <stdio.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <unistd.h>
#include <stdlib.h>
#define SIZE argc-1
int main(int argc, char **argv)
{
int userInput[SIZE];
int temp;
int uiSize = sizeof(userInput)/sizeof(userInput[0]);
int pipeCom[2];
pipe(pipeCom);
printf("CS201 - Assignment 3 Regular - Jonathan Vazquez\n");
pid_t pid = fork();
if (pid == 0) {
int sum = 0;
close(pipeCom[1]);
for(int i = 0;i < uiSize; i++){
read(pipeCom[0], &temp, sizeof(temp));
sum += temp;
temp = 0;
}
return sum;
}else {
int sum = 0;
for(int i = 1; i < argc; i++){
userInput[i] = atoi(argv[i]);
}
close(pipeCom[0]);
for(int i = 1; i < uiSize+1;i++){
write(pipeCom[1], &userInput[i], sizeof(userInput));
}
int status;
wait(&status);
sum = WEXITSTATUS(status);
printf("sum = %d\n", sum);
return 0;
}
}
The return value of the child's main function (the 'sum' you are returning here) is accessable to the parent as the child's exit status. The exit status is limited to 8 bits (not a full integer), so it is generally only used to return a limited error code rather than a value, but it may be big enough for your purposes.
To get the child's exit code in the parent, you need to pass a pointer to a status variable to wait instead of NULL. Replace the wait(NULL) line with:
int status;
wait(&status);
sum = WEXITSTATUS(status);
Alternately (and recommended as 8 bits is usually not enough), you can create a second pipe going from the child back to the parent, and have the child write the sum to that pipe and have the parent read it.
I am trying to print out the Fobonacci sequence according to how many numbers of it the user would like. I.e. if the user inputs 5, the output will be 1,1,2,3,5. So I setup a loop in just a normal C program to do this:
for(int m=1; m<=a;m++)
{
i = (pow(c, m)-(pow(v, m)))/b;
printf("%d\n",(int)round(i));
}
This for loop gives me the desired output I am looking for. But, when I put it into a child process of the fork method, the output changes. I.e. if the user inputs 5, the output will be 1,0,2,2,5. Why is this? and is there a way to fix it? Here is my code:
#include <unistd.h>
#include <stdio.h>
#include <sys/wait.h>
#include <math.h>
int var_glb; /* A global variable*/
int main(void)
{
pid_t childPID;
double a;
double c = 1.6180339;
double v = -0.6190339;
double b = 2.236067977;
int i;
childPID = fork();
if(childPID >= 0) // fork was successful
{
if(childPID == 0) // child process
{
printf("\nEnter the first value:");
scanf("%lf", &a);
for(int m=1; m<=a;m++)
{
i = (pow(c, m)-(pow(v, m)))/b;
printf("%d\n",(int)round(i));
}
}
else //Parent process
{
wait(NULL);
printf("\nThis is the parent process running");
return 0;
}
}
else // fork failed
{
printf("\n Fork failed, quitting!!!!!!\n");
return 1;
}
return 0;
}
I would start by fixing your brackets: i = (pow(c, m)-pow(v, m))/b; Also You cannot expect i to be int... i should be float or double
Your problem is not related to forking. The program produces exactly the same result if all the forking is commented out, and everything runs in the parent process. Apparently the algorithm is incorrect in some way.
So I found that the problem was that i declared the variable i as an int instead of a double, as I had did in another application, thanks for you help though, I will definitely use all of your suggestions to strengthen my code.
So I'm getting into Concurrent Programming, but for some reason I can't even get the basics to work. I have a file called fork.c, which contains a method main. In this method main I fork twice, into child processes 1 and 2.
In child 1, I print the character 'A' 50 times.
In child 2, I print the character 'B' 50 times.
When I run my code, I get the output AAAAA...AAAABBBBBB....BBBBBB. But never something like ABABABABABABAB.... In fact, sometimes I even get BBBBB....BBBBAAAA....AAAAA.
So why am I experiencing this behavior? Perhaps I'm going about it completely wrong.
#include <stdlib.h>
#include <stdio.h>
void my_char(char n) {
write(1, &n, 1);
}
int main() {
int status;
pid_t child1, child2;
if (!(child1 = fork())) {
// first childi
int a;
for (a = 0; a < 50; a++) {
my_char('A');
}
exit(0);
} else if (!(child2 = fork())) {
// second child
int a;
for (a = 0; a < 50; a++) {
my_char('B');
}
exit(0);
} else {
// parent
wait(&child1);
wait(&child2);
my_char('\n');
}
return 0;
}
They are running concurrently, but the processes end almost immediately after being started. In other words, they're too short to actually get any real overlap.
EDIT:
The time needed to start another process is longer than the time it takes to run them. Therefore the chance of overlap is small. (there are also buffering issues which I'll omit)
You need each process to do more work than that. Try printing more than 50. Printing more than 10000 will probably be enough.
I think this is much easier to figure how fork() works:
#include <stdlib.h>
#include <stdio.h>
int main() {
pid_t child1, child2;
printf("Start\n");
if (!(child1 = fork())) {
// first childi
printf("\tChild 1\n");
sleep(5);
exit(0);
} else if (!(child2 = fork())) {
// second child
printf("\tChild 2\n");
sleep(5);
exit(0);
} else {
// parent
printf("Parent\n");
wait(&child1);
printf("got exit status from child 1\n");
wait(&child2);
printf("got exit status from child 2\n");
}
return 0;
}
...and here is the output:
Start
Child 1
Parent
Child 2
got exit status from child 1
got exit status from child 1