fork() understanding, about execution and children - unix
I'm just starting to fork() and I'm having some difficulties understanding the parallel execution. I've found this example code and I want to know if the first time it will go true or false (I know if pid1==0 it means it's a child, etc). I also want to know how many copies (children will be created) and some details on the general execution.
I have tried to run it and added the return 0; (my original source didn't have it) just to see if exits... but as you can see it "waits"
http://i.imgur.com/D3XEFgs.png
int main(void)
{
int pid1, pid2, pid3, pid4;
pid1=fork();
if (pid1!=0)
{
pid2=fork();
pid3=fork();
printf("\t\t IF(TRUE) pid1=%d and pid2=%d and pid3=%d\n",
pid1, pid2, pid3);
}
else
{
pid4=fork();
printf("\nIF(False) FATHER is talking with pid1=%d and pid4=%d\n",
pid1, pid4);
}
return 0;
}
This program creates five descendant processes, and makes six calls to printf, of which four will be the IF(TRUE) message and two will be IF(FALSE). Here is an ASCII-art diagram of the control flow; every time it branches, both sides are executed, with the parent going straight down and the child to the right. The numbers are the fork calls initializing the pid1, pid2, ... variables, the letters T and F are the IF(TRUE) and IF(FALSE) messages, and the _ is the return 0 at the end of the function. This program does not wait for anything; all control flow paths reach the return 0 eventually.
|
1
|\------\
2 4
|\--\ |\
3 3 | |
|\ |\ | |
T T T T F F
| | | | | |
_ _ _ _ _ _
The output messages may appear in any order. And it's possible that the topmost parent process will exit (returning control to the shell) before all of the descendant processes have written their messages, so (as is visible in your screeenshot) the shell prompt may get jumbled up with the messages, too.
Note that, going by the text of the messages, you have your if conditional backward: pid1 != 0 is true in the parent, not the child.
Both true and false will be used on the first time.
fork() copies the program (creates 1 child) and both programs continue execution from that point. The child process will take one branch and the parent the other.
The number of fork()s is as follows:
You start with 1 process
After pid1 -> +1 processes
Parent Branch
After pid4 -> +1 processes
Child Branch
After pid2 -> +1 processes
BOTH of the newly created processes run fork() for pid3, so after pid3 -> +2 processes
You get 5 children + the original process.
Related
Code for #into: is related to the code for #inject:into: , but must be solving a different problem. Explain the difference?
What does this do, and is there a simpler way to write it? Collection>>into: a2block | all pair | all := ([:allIn :each| allIn key key: allIn value. each]) -> (pair := nil -> a2block). pair key: all. self inject: all into: [:allIn :each| allIn value: (allIn key value: allIn value value: each). allIn]. ^all value
If you want to find out, the best way is to try it, possibly step by step thru debugger. For example, try: (1 to: 4) into: #+. (1 to: 4) into: #*. You'll see a form of reduction. So it's like inject:into: but without injecting anything. The a2block will consume first two elements, then result of this and 3rd element, etc... So we must understand the selector name as inject:into: without inject:: like the implementation, it's already a crooked way to name things. This is implemented in Squeak as reduce:, except that reduce: would be well too obvious as a selector, and except that it would raise an Error if sent to an empty collection, contrarily to this which will answer the strange recursive artifact. The all artifact contains a block to be executed for reduction as key, and current value of reduction as value. At first step, it arranges to replace the block to be executed with a2block, and the first value by first element. But the recursive structure used to achieve the replacement is... un-necessarily complex. A bit less obfuscated way to write the same thing would be: into: a2block | block | self ifEmpty: [self error: 'receiver of into: shall not be empty']. block := [:newBlock :each| block := newBlock. each]. ^self inject: a2block into: [:accum :each| block value: accum value: each] That's more or less the same principle: at first iteration, the block is replaced by the reduction block (a2block), and first element is accumulated. The reduction only begins at 2nd iteration. The alternative is to check for first iteration inside the loop... One way to do it: into: a2block | first | self ifEmpty: [self error: 'receiver of into: shall not be empty']. first := Object new. ^self inject: first into: [:accum :each | accum == first ifTrue: [each] ifFalse: [a2block value: accum value: each]]. There are many other ways to write it, more explicitely using a boolean to test for first iteration...
RTE in the bst program
I have to check if this is BST or not i have implemented recursion and it is giving run time error for the tree level order 2 N 7 N 6 N 5 N 9 N 2 N 6 bool isBST(Node* root) { if(root==NULL) return 1; if(root->left==NULL && root->right==NULL) return 1; if((root->data)<(root->left->data)) return 0; if( (root->data)>(root->right->data)) return 0; if(root->right==NULL) return isBST(root->left); if(root->left==NULL) return isBST(root->right); if(!isBST(root->left) || !isBST(root->right)) { return 0; } return 1; }
Your code may dereference a null pointer. For instance, if root has a right child, but not a left child, then this code will be executed which performs an invalid dereference: if((root->data)<(root->left->data)) But even if you add the necessary checks to avoid such invalid dereferencing, the algorithm is not correct. It is not true that the following conditions define a valid BST: The left child of a node is either null or has a value that is not greater than the node's own value, AND The right child of a node is either null or has a value that is not less than the node's own value, AND The above is also true for the left and right child (recursive step) For instance, this would all be true for this tree: 5 / \ 2 8 \ 7 ... but this tree is not a valid BST, because 7 is greater than 5, which is not allowed. All values in the left subtree of a node must not be greater than the node's own value. Your code only checks this for the direct child, but it should make sure that this is also true for any other descendants in that left subtree. The common way to make a correct verification, is to pass to the recursive call a window (minimum and maximum) of values which the subtree may contain.
Linked List: Copy List Using Recursive
I am new to Linked List. I am trying to write a CopyList() code that can copy a linked list to a new list. There's a unique version using recursive and I don't really understand: struct node { int data; struct node *next; }; struct node* CopyList(struct node* head) { struct node* current = head; if (current == NULL) return NULL; else { struct node* newList = malloc(sizeof(struct node)); newList->data = current->data; newList->next = CopyList(current->next); // recur for the rest return(newList); } } My trouble of understanding is the line newList->next = CopyList(current->next); So how does this work for copying and why?
Lets take an example. If you simply put the current->next in newList->next i.e newList->next = current->next. Then it will point to the next node of old list only. Not to the next node of new list. So to make a different list (Copy list). You separately have to make a new node and return it to point to next of previous node.
This is the magical recursive statement. newList->next = CopyList(current->next); For each recursive step, this will delegate the task of creating remaining linked list, to the next recursive call. For example: List is getting created from right to left. CopyList (1->2->3->4->5) | |---------1-> CopyList (2->3->4->5) | |---------2-> CopyList (3->4->5) | |---------3-> CopyList (4->5) | |---------4-> CopyList (5) | |---------5-> CopyList (NULL) Returns 5 Returns 4->5->NULL Returns 3->4->5->NULL Returns 2->3->4->5->NULL Returns 1->2->3->4->5->NULL As per wiki A simple base case (or cases)—a terminating scenario that does not use recursion to produce an answer. A set of rules that reduce all other cases toward the base case. In your case, terminating scenario is if list reaches the end, just return null and a new node is created at every step that leads the list to the base scenario.
This is the recursion step. The previous two commands create a new node and copy the head of the current list to that object. Now, instead of iterating (looping) through the rest of the list, we call CopyList to copy the remainder of the list -- everything except the head node that we just copied. CopyList returns a copy of that remainder, which we simply append to the copy of the head node ... and we're done.
Erlang sudoku solver - How to find the empty spots and try possible values recursively
I have been busy with a sudoku solver in Erlang yesterday and today. The working functionality I have now is that I can check if a sudoku in the form of a list, e.g., [6,7,1,8,2,3,4,9,5,5,4,9,1,7,6,3,2,8,3,2,8,5,4,9,1,6,7,1,3,2,6,5,7,8,4,9,9,8,6,4,1,2,5,7,3,4,5,7,3,9,8,6,1,2,8,9,3,2,6,4,7,5,1,7,1,4,9,3,5,2,8,6,2,6,5,7,8,1,9,3,4]. is valid or not by looking at the constraints (no duplicates in squares, rows, and columns). This function is called valid(S) which takes a sudoku S and returns true if it is a valid sudoku and false if it is not. The function ignores 0's, which are used to represent empty values. This is an example of the same sudoku with some random empty values: [0,7,1,8,2,3,4,0,5,5,4,9,0,7,6,3,2,8,3,0,8,5,0,9,1,6,7,1,3,2,6,5,7,8,4,9,0,8,6,4,1,2,5,7,0,4,5,7,3,9,8,6,1,0,8,9,3,2,6,4,7,5,1,7,1,4,9,3,0,2,8,6,2,6,5,7,8,1,9,3,4]. The next step is to find the first 0 in the list, and try a value from 1 to 9 and check if it produces a valid sudoku. If it does we can continue to the next 0 and try values there and see if it is valid or not. Once we cannot go further we go back to the previous 0 and try the next values et cetera until we end up with a solved sudoku. The code I have so far looks like this (based on someone who got it almost working): solve(First,Nom,[_|Last]) -> try_values({First,Nom,Last},pos()). try_values(_,[]) -> {error, "No solution found"}; try_values({First,Nom,Last},[N|Pos]) -> case valid(First++[N]++Last) of true -> case solve({First++[N]},Nom,Last) of {ok,_} -> {ok, "Result"}; {error,_} -> try_values({First,N,Last},Pos) end; false -> try_values({First,N,Last},Pos) end. pos() is a list consisting of the values from 1 to 9. The idea is that we enter an empty list for First and a Sudoku list for [_|Last] in which we look for a 0 (Nom?). Then we try a value and if the list that results is valid according to our function we continue till we fail the position or have a result. When we fail we return a new try_values with remaining (Pos) values of our possibitilies. Naturally, this does not work and returns: 5> sudoku:solve([],0,S). ** exception error: bad argument in operator ++/2 called as {[6]} ++ [1,1,8,2,3,4,0,5,5,4,9,0,7,6,3,2,8,3,2,8,5,4,9,1,6,7,1,3,2|...] in call from sudoku:try_values/2 (sudoku.erl, line 140) in call from sudoku:try_values/2 (sudoku.erl, line 142) With my inexperience I cannot grasp what I need to do to make the code logical and working. I would really appreciate it if someone with more experience could give me some pointers.
try_values([], []) -> error("No solution found"); try_values([Solution], []) -> Solution; try_values(_, []) -> error("Bad sudoku: multiple solutions"); try_values(Heads, [0|Tail]) -> NewHeads = case Heads of [] -> [[P] || P <- pos()]; _ -> [Head++[P] || P <- pos(), Head <- Heads] end, ValidHeads = [Head || Head <- NewHeads, valid(Head++Tail)], try_values(ValidHeads, Tail); try_values([], [H|Tail]) -> try_values([[H]], Tail); try_values(Heads, [H|Tail]) -> try_values([Head++[H] || Head <- Heads], Tail). solve(Board) -> case valid(Board) of true -> try_values([], Board); false -> error("No solution found") end. try_values does what you described. It builds solution by going through Board, trying all possible solutions (from pos()) when it finds 0 and collecting valid solutions in ValidHeads to pass them further to continue. Thus, it goes all possible ways, if at some point there are multiple valid sudoku they all will be added to Heads and will be tested on validity on following steps. solve is just a wrapper to call try_values([], Board). Basically, the way to iterate recursively over 0's is to skip all non-zeros (2 last try_values expression) and do the job on zeros (fourth try_values expression). First three try_values expressions check if solution is exist and single and return it in that case.
Why does not init:stop() terminate directly?
My code for display all days in this year. I don't understand why if NewSec =< EndSec -> init:stop() end did not execute the first time in run_calendar? I expect init:stop() could be executed first time but it is not. What is wrong? Code: -module(cal). -export([main/0]). main() -> StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}), EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}), run_calendar(StartSec,EndSec). run_calendar(CurSec, EndSec) -> {Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec), io:format("~p~n", [Date]), NewSec = CurSec + 60*60*24, if NewSec =< EndSec -> init:stop() end, run_calendar(NewSec, EndSec). Result: wk# erlc cal.erl wk# erl -noshell -s cal main {2009,1,1} {2009,1,2} {2009,1,3} {2009,1,4} {2009,1,5} ... {2009,12,22} {2009,12,23} {2009,12,24} {2009,12,25} {2009,12,26} {2009,12,27} {2009,12,28} {2009,12,29} {2009,12,30} {2009,12,31} wk#
I believe that init:stop() is an asynchronous process that will attempt to shut down the runtime smoothly. According to the docs, "All applications are taken down smoothly, all code is unloaded, and all ports are closed before the system terminates." It probably takes a while to actually stop, because you have an actively running process. If you change "init:stop()" to "exit(stop)", it will terminate immediately: 3> cal:main(). {2009,1,1} ** exception exit: stop in function cal:run_calendar/2
Init:stop is asynchronous and it will take time to quit. An alternate way would be to wrap up the test in the call itself and use pattern matching to terminate the loop: -module(cal). -export([main/0]). main() -> StartSec = calendar:datetime_to_gregorian_seconds({{2009,1,1},{0,0,0}}), EndSec = calendar:datetime_to_gregorian_seconds({{2009,12,31},{0,0,0}}), run_calendar(false, StartSec, EndSec). run_calendar(true, _StartSec, _EndSec) -> finished; run_calendar(false, CurSec, EndSec) -> {Date,_Time} = calendar:gregorian_seconds_to_datetime(CurSec), io:format("~p~n", [Date]), NewSec = CurSec + 60*60*24, run_calendar(NewSec =< EndSec, NewSec, EndSec). (or something similar, hopefully you get the idea)
You have a mistake in your if statement You said if NewSec =< EndSec -> init:stop() end, This is incorrect. You have to write something like: if A =< B -> do something ...; true -> do something else end The if syntax is if Condition1 -> Actions1; Condition2 -> Actions2; ... end One of these conditions must always be true. Why is this? Erlang is a functional language, not a statement language. In an functional language every expression must have a value. if is an expression, so it must have a value. The value of (if 2 > 1 -> 3 end) is 3 but what is the value of (if 1 > 2 -> 3 end) - answer it has no value - but it must have a value everything must have a value. In a statement language everything is evaluated for its side effect -so this would be a valid construction. In Erlang you will generate an exception. So your code generates an exception - which you don't trap so you don't see it and init:stop() never gets called ...