Yesterday, i had a interview and i was asked this question of code snippet using fork() .
void main()
{............
for (int k=1;k<=10;k++)
{
pid[k]=fork();
if(!pid[k])
execvp(.....);
}
}
According to my understanding, i told 1024 total processes will be there including the parent as 2^n -1 = 1023 + 1 parent where n = total forks
But, the interviewer replied that my answer was wrong.
What is wrong with my understanding?
Given this code
pid[k]=fork();
if(!pid[k])
execvp(.....);
and reading the man page of fork which states that
On success, the PID of the child process is returned in the parent,
and 0 is returned in the child.
we know that the child process will perform the exec call (and go on executing a different program), whereas the parent will loop and create another child.
This means that a child will be created for each iteration of the loop, in this case 10 times. So, the answer is 10 children + 1 parent = 11.
Now, if the program that gets started by exec is the same program, the fun will stop only when the computer's memory is exhausted: on every iteration 10 programs will each create 10 children, which each will create 10 children, and so on. A pecularity of fork() is that parent and child get an image of the same variables (which would lead to a predictable number of children, ie some figure related to a power of 2), obviously this isn't true when a program gets exec'd, which means that available memory will be the only limit.
Related
Code Snippet:
my $kill=0;
my #array1 = ("abc", "def","ghi");
&runSmokesAndMonitor;
sub runSmokesAndMonitor {
foreach my $smokeTestVarDirName (#array1) {
if ($pid =fork()) {
print "parent\n"; ### Have some other action items as well here in parent
}
else {
$kill++;
print "Value of kill is $kill\n";
exit 0;
}
}
}
Here, I am getting output:
parent
Value of kill is 1
parent
Value of kill is 1
parent
Value of kill is 1
Required/Expected: (As $kill is global variable, so values of $kill must have updated wherever new value would have assigned)
parent
Value of kill is 1
parent
Value of kill is 2
parent
Value of kill is 3
parent
Why is the output not as expected, and how can i achieve it?
A child created by fork is a new process with its own address space. Global variables are per process only, not global per user or per system or even global between all instances of a software running in the world. That's why changes to a global variable are only reflected in the current process.
If you need to share information between processes you need IPC (inter process communication), i.e. things like sockets, pipes, shared memory etc - see perlipc for more. There are ways to make sharing variables across processes easier, like IPC::Shareable.
i'm new to operating systems and i found this code , and i don't understand why certain outputs like : abc , we can't get
suppose we have this code in c :
int main()
{
if(fork()==0)
printf("a");
else
{
printf("b");
waitpid(-1);
}
printf("c");
return 0;
}
waitpid() waits for a child process to terminate.
can the child process be terminated in abnormal way ? so that we can have this outputs : abc, bc ?
according to at least the linux manpage for fork:
RETURN VALUE
On success, the PID of the child process is returned in the parent, and
0 is returned in the child. On failure, -1 is returned in the parent,
no child process is created, and errno is set appropriately.
so if your child program isn't ever created the entire output will be c for the parent process and nothing for the child process, because it never came to be.
Also it is possible that the parent process is killed before it can output a, or c, then you'll only get the child's output, bc. or maybe the parent is killed before it can even fork! there are lots of possibilities and with good timing (and some calls to the sleep function inbetween) you could probably reproduce them.
I have the model which I posted before on Stack. I am currently running the iterations through 5 Flow Chart blocks contain enter block and service block. when agent fill service block 5 in flow chart 5, the exit block should start to fill block one and so on. I have used While infinite loop to loop between the five flow chart blocks but it isn't working.
while(true)
{
for (Curing_Drying currProcess : collection) {
if (currProcess.allowedDay == (int)time(DAY)) {
currProcess.enter.take(agent);
}
}
if (queue10.size() <= Throughtput1){
break;
}
}
Image for further illustration 1
Image for further illustration 2
Wondering if someone can tell me what is wrong in the code.
Based on the description and the pictures provided, it isn't clear why the while loop is necessary. The On exit action is executed for each Agent arrival to the Exit block. It seems that the intention is to find the appropriate Curing_Drying block based on number of days since the model start time? If so, then just iterating through the collection is enough.
Also, it is generally a good practice to provide more meaningful names to collections. Using simply collection doesn't say anything about the contents and can get pretty confusing later on.
I'm new to perl. I have a process that uses poe::wheel::run to kick off multiple child processes. I'm trying to find a way to gracefully stop the wheel processes when SIG{INT} signal received.
I've been able to gracefully stop the child processes when it detects the parent isn't running.
I have a sig_int_handler that kills all processes (parent and children)
I cannot find a way for the child processes to detect and act on a sig_int_flag set to true. Is this possible???
I'd like it to ...
receive SIG{INT}
set variable to sig_int_flag = 1 (or something)
handler sends message that signal received then sleep for 30 seconds.
after 30 seconds -- kill all processes.
meanwhile the wheel is on a loop that
processes a file
checks for and breaks out
if parent pid not detected or
if sig_int_flag == 1 (not working)
otherwise processes next file
The idea is to give the wheel 30 seconds to finish what it's doing. if the child processes are not dead on their own -- we kill them.
Is this possible?
Thanks
I cannot find a way for the child processes to detect and act on a sig_int_flag set to true. Is this possible???
For a child to see the same flag which the parent sets, the flag has to reside in shared memory.
Another way is to send a signal to the child where a handler sets the flag.
re:
http://www.perlmonks.org/?node_id=786942
when:
$manager->start and next;
&dowork();
The parent returns true ($pid), and goes to the next iteration of the surrounding loop. The child returns 0, and does the work.
If I understand correctly, if we reach the number of maximum children, the $manager->start will return 0, and the parent will do the work? If so, what's the best way to stop the parent from doing any work?
Parallel::ForkManager
start will always start a child. It may have to wait for one of the child to end (when the maximum number of children are running), but it's fully prepared to do that.
It does not return zero except in he child. (It dies on error.)